の形式で読み取り/書き込みを行う必要がある単純なMatrixクラスがありますa[index1][index2]
。
例えば:
Matrix a;
a[1][2] = 5;
それをC++でどのように実装しますか?ありがとう。
の形式で読み取り/書き込みを行う必要がある単純なMatrixクラスがありますa[index1][index2]
。
例えば:
Matrix a;
a[1][2] = 5;
それをC++でどのように実装しますか?ありがとう。
これは、まさにあなたが望むことを実行する素晴らしい基本実装です。
更新(2013年9月26日):コードを大幅に改善しました。
テンプレートのタイプT
は、の要件を満たす必要があるだけstd::vector
です。
#include <vector>
#include <stdexcept>
template<typename T>
class matrix {
class row {
std::vector<T> values;
public:
row(std::size_t n)
: values(n, T()) {}
T& operator[] (std::size_t index) {
if (index < values.size())
return values[index];
else
throw std::domain_error("Matrix column index out of bounds.");
}
const T& operator[] (std::size_t index) const {
if (index < values.size())
return values[index];
else
throw std::domain_error("Matrix column index out of bounds.");
}
std::size_t size() const { return values.size(); }
};
std::vector<row> rows;
public:
matrix(std::size_t m, std::size_t n)
: rows(m, row(n)) {}
row& operator[](std::size_t index) {
if (index < rows.size())
return rows[index];
else
throw std::domain_error("Matrix row index out of bounds.");
}
const row& operator[](std::size_t index) const {
if (index < rows.size())
return rows[index];
else
throw std::domain_error("Matrix row index out of bounds.");
}
std::size_t row_count() const { return rows.size(); }
std::size_t col_count() const {
if (rows.size()) return rows[0].size();
return 0;
}
std::size_t size() const { return row_count() * col_count(); }
};
便宜上、このヘルパーを使用してマトリックスを印刷できます。
#include <ostream>
template<typename T>
std::ostream& operator <<(std::ostream& o, const matrix<T>& mat) {
for (std::size_t i = 0u; i < mat.row_count(); ++i) {
for (std::size_t j = 0u; j < mat.col_count(); ++j) {
o << mat[i][j] << ' ';
}
o << '\n';
}
return o;
}
そしてあなたのためだけに、これをテストするための使用例:
int main() {
matrix<int> mat_0(2, 3);
matrix<double> mat_1(1, 2);
mat_0[0][0] = 2;
mat_0[0][1] = 3;
mat_0[0][2] = 4;
mat_0[1][0] = 3;
mat_0[1][1] = 7;
mat_0[1][2] = 9;
mat_1[0][0] = 0.43;
mat_1[0][1] = 213.01;
std::cout << mat_0;
std::cout << '\n';
std::cout << mat_1;
return 0;
}
Matrix::operator[]
マトリックス内の列を表すヘルパークラスを返すように、オーバーロードする必要があります。そのヘルパークラスはoperator[]
、その列内の要素にアクセスするためにオーバーロードする必要もあります。
ただし、この方法で実装すると、複雑になりすぎる可能性があります。代わりに、実装operator()
して2つのインデックスを引数として使用する方が簡単な場合があります。
int& Matrix::operator()(int i, int j)
{
return internal_array[i][j];
}
要素にrefを返すネストclass RowType
を定義し、の要素にrefを返すようにを定義します。operator[]
Matrix
Matrix
operator []
RowType
これがテーマのバリエーションです(最初の答えの周り)。int、double、complex、(string !?)などを使用するためにnew-delete .. ahとtemplateを使用しないでください。これは完全な実装ではなく、デバッグもしていません。それは単なるアイデアです。
#include <vector>
template <typename Num>
class Matrix {
public:
class RowType
{ public:
RowType () { }
RowType (unsigned int columnCount):values(columnCount,Num()) {}
int& operator[](unsigned int index) {return values[index];}
const int& operator[](unsigned int index)const{return values[index];}
std::vector<Num> values;
};
Matrix() { }
Matrix(unsigned int rowCount, unsigned int columnCount)
:rows(rowCount, MatrixRow<Num>(columnCount) ) {}
RowType& operator[](unsigned int index) {return rows[index]);}
const RowType& operator[](unsigned int index)const{return rows[index]);}
private: std::vector<RowType<Num>> rows;
};
....
Matrix<int> a(10,10);
a[9][9]=1;
たとえば、1d Matrixクラスを作成し、Matrix1D
その[]
演算子をオーバーロードして、特定のインデックスの値にアクセスできるようにすることができます。
次に、2d Matrixクラスを作成し、Matrix2D
その演算子をオーバーロードして、それに含まれるクラス[]
の1つにアクセスできるようにします。Matrix1D
そうすれば、a
(Matrix2D
)からMatrix1D
withに遷移し[]
、次に2番目の値に遷移します[]
。