アフィリエイト広告を利用しています

広告

posted by fanblog

2018年01月29日

《その264》 問題演習 p.349演習9-8 (1)



新版明解C++中級編 p.349 演習9-8
 (1)〜(3)の各クラステンプレートをインクルードモデルで実現したプログラムを作成せよ。

(1)クラステンプレート Array<>


// Array.h
#ifndef ___ClassTemplate_Array
#define ___ClassTemplate_Array

template <class Type> class Array {
int nelem; // 配列要素数
Type* vec; // 配列先頭要素へのポインタ

// 添字として適なら true、否なら false
bool is_valid_index(int idx) {
return idx >= 0 && idx < nelem;
}

public:
// 添字範囲例外クラス
class IdxRngErr {
const Array* ident;
int idx;
public:
IdxRngErr(const Array* p, int i)
: ident(p), idx(i) { }
int Index() const { return idx; }
};

// コンストラクタ
explicit Array(int size, const Type& v = Type())
: nelem(size) {
vec = new Type[nelem];
for (int i = 0; i < nelem; i++)
vec[i] = v; // 全要素の初期値 v
}

// コピーコンストラクタ
Array(const Array<Type>& x) {
if (&x == this) {
nelem = 0;
vec = NULL;
}
else {
nelem = x.nelem;
vec = new Type[nelem];
for (int i = 0; i < nelem; i++)
vec[i] = x.vec[i];
}
}

// デストラクタ
~Array() { delete[] vec; }

// 要素数 nelem のゲッタ
int size() const { return nelem; }

// 代入演算子
Array& operator=(const Array<Type>& x) {
if (&x != this) {
if (nelem != x.nelem) {
delete[] vec;
nelem = x.nelem;
vec = new Type[nelem];
}
for (int i = 0; i < nelem; i++)
vec[i] = x.vec[i];
}
return *this;
}

// 添字演算子[]
Type& operator[](int i) {
// 添字が否なら、添字範囲例外を throw
if (!is_valid_index(i))
throw IdxRngErr(this, i);
return vec[i];
}

// 添字演算子[]
const Type& operator[](int i) const {
// 添字が否なら、添字範囲例外を throw
if (!is_valid_index(i))
throw IdxRngErr(this, i);
return vec[i];
}
};

#endif




// ArrayTest.cpp
#include <iostream>
#include "Array.h"
using namespace std;

int main() {
try {
int no;
Array<int> x(5);
Array<double> y(8);

cout << "データ数:";
cin >> no;

for (int i = 0; i < no; i++) {
x[i] = i;
y[i] = 0.1 * i;
cout << "x[" << i << "] = " << x[i] << " "
<< "y[" << i << "] = " << y[i] << '\n';
}
}
catch (bad_alloc) {
cout << "メモリの確保に失敗しました。\n";
return 1;
}
catch (const Array<int>::IdxRngErr& x) {
cout << "添字オーバフロー Array<int>:"
<< x.Index() << '\n';
return 1;
}
catch (const Array<double>::IdxRngErr& x) {
cout << "添字オーバフロー Array<double>:"
<< x.Index() << '\n';
return 1;
}
}


 問題で与えられた Array.h を、Array.h と ArrayImplementation.h の2つに分けて、
インクルードモデルを実現しました。



// 解答


// Array.h
#ifndef ___ClassTemplateArray
#define ___ClassTemplateArray

template <class Type> class Array {
int nelem; // 配列要素数
Type* vec; // 配列先頭要素へのポインタ

// 添字として適なら true、否なら false
bool is_valid_index(int idx);

public:
// 添字範囲例外クラス
class IdxRngErr {
const Array* ident;
int idx;
public:
IdxRngErr(const Array* p, int i);
int Index() const;
};

// コンストラクタ
explicit Array(int size, const Type& v = Type());

// コピーコンストラクタ
Array(const Array<Type>& x);

// デストラクタ
~Array();

// 要素数 nelem のゲッタ
int size() const;

// 代入演算子
Array& operator=(const Array<Type>& x);

// 添字演算子[]
Type& operator[](int i);

// 添字演算子[]
const Type& operator[](int i) const;
};

#include "ArrayImplementation.h"

#endif




// ArrayImplementation.h
#ifndef ___ClassTemplateArrayImplementation
#define ___ClassTemplateArrayImplementation

template <class Type>
bool Array<Type>::is_valid_index(int idx) {
return idx >= 0 && idx < nelem;
}

template <class Type>
Array<Type>::IdxRngErr
::IdxRngErr(const Array* p, int i)
: ident(p), idx(i) { }

template <class Type>
int Array<Type>::IdxRngErr
::Index() const { return idx; }


template<class Type>
Array<Type>::Array(int size, const Type& v)
: nelem(size) {
vec = new Type[nelem];
for (int i = 0; i < nelem; i++)
vec[i] = v;
}

template<class Type>
Array<Type>::Array(const Array<Type>& x) {
if (&x == this) {
nelem = 0;
vec = NULL;
}
else {
nelem = x.nelem;
vec = new Type[nelem];
for (int i = 0; i < nelem; i++)
vec[i] = x.vec[i];
}
}

template<class Type>
Array<Type>::~Array() { delete[] vec; }

template<class Type>
int Array<Type>::size() const {
return nelem;
}

template<class Type>
Array<Type>& Array<Type>
::operator=(const Array<Type>& x) {
if (&x != this) {
if (nelem != x.nelem) {
delete[] vec;
nelem = x.nelem;
vec = new Type[nelem];
}
for (int i = 0; i < nelem; i++)
vec[i] = x.vec[i];
}
return *this;
}

template<class Type>
Type& Array<Type>::operator[](int i) {
if (!is_valid_index(i))
throw IdxRngErr(this, i);
return vec[i];
}

template<class Type>
const Type& Array<Type>
::operator[](int i) const {
if (!is_valid_index(i))
throw IdxRngErr(this, i);
return vec[i];
}

#endif




// ArrayTest.cpp
#include <iostream>
#include "Array.h"
using namespace std;

int main() {
try {
int no;
Array<int> x(5);
Array<double> y(8);

cout << "データ数:";
cin >> no;

for (int i = 0; i < no; i++) {
x[i] = i;
y[i] = 0.1 * i;
cout << "x[" << i << "] = " << x[i] << " "
<< "y[" << i << "] = " << y[i] << '\n';
}
}
catch (bad_alloc) {
cout << "メモリの確保に失敗しました。\n";
return 1;
}
catch (const Array<int>::IdxRngErr& x) {
cout << "添字オーバフロー Array<int>:"
<< x.Index() << '\n';
return 1;
}
catch (const Array<double>::IdxRngErr& x) {
cout << "添字オーバフロー Array<double>:"
<< x.Index() << '\n';
return 1;
}
}

f09_0801.png




この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/7254208
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。