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

広告

posted by fanblog

2018年01月22日

《その250》 問題演習 p.329演習9-4



新版明解C++中級編 p.329 演習9-4
 前回《249》演習9-3 の問題文に ヘッダファイル Array.h のコードを記載してありますが、そのヘッダにある Array<>クラステンプレートは、配列要素を1つの添字でアクセスするもので、1次元配列に相当します。
Array<>クラステンプレートを参考にして、
2つの添字をもつ2次元配列クラステンプレート Matrix<> を作成せよ。




// 解答


// Matrix.h
#ifndef ___ClassTemplate_Matrix
#define ___ClassTemplate_Matrix

template <class Type> class Matrix {
int mm; // 先頭側添字
int nn; // 末尾側添字
Type* vec; // 配列先頭要素へのポインタ

// 添字として適なら true、否なら false
bool is_valid_index(int idx0, int idx1) {
return (idx0 >= 0 && idx0 < mm)
&& (idx1 >= 0 && idx1 < nn);
}

public:
// 添字範囲例外クラス
class IdxRngErr {
const Matrix* ident;
int idx0;
int idx1;
public:
IdxRngErr(const Matrix* x, int i, int j)
: ident(x), idx0(i), idx1(j) { }
int index0() const { return idx0; }
int index1() const { return idx1; }
};

// コンストラクタ
Matrix(
int size0, // 先頭側添字
int size1, // 末尾側添字
const Type& v = Type() // 初期値
) : mm(size0), nn(size1) {
vec = new Type[mm * nn];
for (int i = 0; i < mm; i++)
for(int j = 0; j < nn; j++)
vec[nn * i + j] = v; // 初期値 v
}

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

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

// 先頭側添字のゲッタ
int size0() const { return mm; }

// 末尾側添字のゲッタ
int size1() const { return nn; }

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

// ゲッタ
Type ary(int i, int j) const {
if (!is_valid_index(i, j))
throw IdxRngErr(this, i, j);
return vec[i * nn + j];
}

// ゲッタ かつ セッタ
Type& ary(int i, int j) {
if (!is_valid_index(i, j))
throw IdxRngErr(this, i, j);
return vec[i * nn + j];
}
};

#endif




// p329_9_4.cpp
#include <iomanip>
#include <iostream>
#include "Matrix.h"
using namespace std;

int main() {
cout << "(1) 初期化と値の表示\n";
Matrix<int> a(2, 3);
for (int i = 0; i < a.size0(); i++) {
for (int j = 0; j < a.size1(); j++)
cout << setw(3) << a.ary(i, j) << " ";
cout << '\n';
}

cout << "\n(2) 値の代入と表示\n";
for (int i = 0; i < a.size0(); i++)
for (int j = 0; j < a.size1(); j++)
a.ary(i, j) = 3 * i + j;

for (int i = 0; i < a.size0(); i++) {
for (int j = 0; j < a.size1(); j++)
cout << setw(3) << a.ary(i, j) << " ";
cout << '\n';
}

cout << "\n(3) コピーコンストラクタ\n";
Matrix<int> b(a);
b.ary(1, 1) = 99; // ary(1, 1) に 99 を代入
for (int i = 0; i < b.size0(); i++) {
for (int j = 0; j < b.size1(); j++)
cout << setw(3) << b.ary(i, j) << " ";
cout << '\n';
}

cout << "\n(4) 代入,添字の確認\n";
Matrix<int> c(5, 6);
cout << "配列 c の先頭側添字 : " << c.size0() << '\n'
<< " 末尾側添字 : " << c.size1() << "\n\n";

c = a;
cout << "配列 c の先頭側添字 : " << c.size0() << '\n'
<< " 末尾側添字 : " << c.size1() << '\n';

cout << "\n(5) 代入後の値を表示\n";
for (int i = 0; i < c.size0(); i++) {
for (int j = 0; j < c.size1(); j++)
cout << setw(3) << c.ary(i, j) << " ";
cout << '\n';
}

cout << "\n(6) 添字エラー\n";
try {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++)
cout << setw(3) << c.ary(i, j) << " ";
cout << '\n';
}
}
catch (Matrix<int>::IdxRngErr& e) {
cout << "添字エラー!!\n";
cout << "先頭側添字 : " << e.index0() << '\n'
<< "末尾側添字 : " << e.index1() << "\n\n";
}
}

f09_04.png




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

お名前:

メールアドレス:


ホームページアドレス:

コメント:

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

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

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

 たまに、クリック お願いします 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日以上新しい記事の更新がないブログに表示されております。