I would not use pointers to elements but rather define the Matrix using numeric template parameters. E.g.
template<typename TElem, size_t R, size_t C=R>
class Matrix
{
...
};
Then define internally to that class some types and the data storage, e.g.
...
public:
typedef TElem ElementType;
typedef ElementType RowType[C];
typedef RowType MatrixType[R];
private:
MatrixType _matrix;
...
Followed by some constructors for that class, e.g.
...
public:
Matrix()
{
for(size_t i = 0; i < R; ++i) for(int j = 0; j < C; ++j) _matrix[i][j] = 0;
}
Matrix(const MatrixType &matrix)
{
for(size_t i = 0; i < R; ++i) for(int j = 0; j < C; ++j) _matrix[i][j] = matrix[i][j];
}
...
Finally implement the adding and some print facility within that class, e.g.
...
Matrix& addAssign(const Matrix& rhs)
{
for(size_t i = 0; i < R; ++i) for(int j = 0; j < C; ++j) _matrix[i][j] += rhs._matrix[i][j];
return *this;
}
void print(ostream& out, const string& name) const
{
out << "### " << name << " ###" << endl;
for(size_t i = 0; i < R; ++i)
{
for(int j = 0; j < C; ++j)
{
if (j > 0) out << ",";
out << _matrix[i][j];
}
out << endl;
}
}
...
Note that I implemented in-place adding, i.e. the matrix gets modified by adding the
rhs
elements to the own elements.
Using:
typedef Matrix<double,2,3> M23;
M23 a;
M23 b(a);
M23::MatrixType m = {{1,0,0},{0,1,0}};
M23 c(m);
a.print(cout, "a");
b.print(cout, "b");
c.print(cout, "c");
c.addAssign(c);
c.print(cout, "c");
Result:
### a ###
0,0,0
0,0,0
### b ###
0,0,0
0,0,0
### c ###
1,0,0
0,1,0
### c ###
2,0,0
0,2,0
Cheers
Andi