I just looked at what I pasted and I sincerely apologize |
You can edit your posts to add code tags.
Why do you have a mix of raw arrays and std::vectors? Why don't you implement Matrix with std::vector?
Note:
1 2 3 4 5
|
array_ = new Object * [rows];
for ( int i=0; i<rows; i++ )
{
array_[i] = new Object[columns];
}
| |
Yes, that's what they all do. Raw could be:
1 2 3 4 5 6
|
array_ = new Object * [rows];
array_[0] = new Object [rows*cols];
for ( int r=1; r<rows; ++r )
{
array_[r] = array_[0] + r*cols;
}
| |
That is simpler to deallocate too:
1 2 3
|
delete [] array_[0];
delete [] array_;
array_ = nullptr;
| |
Whatever implementation you do choose, pack the allocation and deallocation into helper functions, for you do them in multiple places and logical typos can easily creep in.
For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
Matrix( const Matrix &rhs )
{
array_ = new Object *[rhs.num_rows_];
for ( int i=0; i<num_rows_; i++ ) // use of uninitialized value
{
array_[i] = new Object[num_columns_]; // use of uninitialized value
}
for ( int i=0; i<rhs.num_rows_; i++ )
{
for( int j=0; j<rhs.num_columns_; j++ )
{
array_[i][j] = rhs[i][j]; // THIS IS AWESOME *
}
}
num_columns_ = rhs.num_columns_;
num_rows_ = rhs.num_rows_;
}
| |
* What is so mind-boggling about that?
The rhs IS-A Matrix. You do call
Matrix::operator[](int)
a total of
rhs.num_rows_ * rhs.num_columns_
times.
Each call constructs temporary unnamed
std::vector<Object>
, whose operator[] you then call.
Once.
The first errors you would have avoided by use of initializer list syntax:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
Matrix( const Matrix &rhs )
: num_columns_( rhs.num_columns_ ),
num_rows_( rhs.num_rows_ ),
array_( new Object* [rhs.num_rows_] );
{
for ( int i=0; i<num_rows_; i++ ) // ok
{
array_[i] = new Object[num_columns_]; // ok
}
for ( int r=0; r<num_rows_; ++r )
{
std::copy( rhs.array_[r], rhs.array_[r] + num_columns_, array_[r] ); // fancy
}
}
| |