Your copy constructor and copy assignment operator should have the parameter as const Matrix&. After all, it should make sense to copy a matrix that is constant.
I notice that the copy assignment operator copies the row count and column count, i.e., the number of rows and columns of the source matrix could differ from the destination matrix. However, it makes no attempt to allocate space if the source matrix has more rows or columns than the destination matrix.
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
Initially, I had them as const Matrix&, however, as I am using the overloaded () operator inside the constructor and assignment operator, I am not allowed to use const.
compilier error:
Code:
error: passing 'const Matrix' as 'this' argument of 'float& Matrix::operator()(int, int)' discards qualifiers
maybe it's just that my () operator is incorectly overloaded:
Code:
float& Matrix::operator()(const int nRow, const int nCol)
{
return m_pfMatrix[nRow * m_nColCount + nCol];
}
as for the copy assignment operator, I'm gonna fix it
thanks for your input!
As laserlight pointed out, the operator= needs to reallocate memory when the matrix size is changing. One easy way to do this is using the copy-and-swap trick that Paul demonstrated earlier.
It bears repeating that std::vector should be preferred to dynamic arrays whenever possible, because it's both safer and easier to work with.
One other point worth mentioning----you should not assume that returning a matrix from a function by value will invoke the copy constructor to create a copy, and the destructor of the matrix that's local to the function. It might; that's the behavior to expect, certainly; but don't assume it must do that, because one common form of compiler optimization tries to remove such unnecessary copies using return value optimization. Whatever it does end up doing will be equivalent to the above, but only if your copy constructor and operator= really do create logical copies. So don't try to get clever with those functions.
@Lindley, thanks for the information on return values and copy constructors!
as for the vector, it was a kind of "requirment" to do it with arrays. But I agree that using a std::vector would be better!
Last edited by replax; March 29th, 2010 at 03:29 PM.
@Lindley, thanks for the information on return values and copy constructors!
as for the vector, it was a kind of "requirment" to do it with arrays. But I agree that using a std::vector would be better!
Yes, usage of vector removes the need to write a copy ctor/assignment op (and destructor).
Also, as Lindley pointed out, your copies should be logically equivalent. In other words, if you replace the original with the copy, the copy must behave exactly the same as the original, regardless of the path of execution your code will take.
A source of bugs is writing copy/assignment functions that really are not making true copies of the object. This is called coding with side-effects. This type of coding is to be avoided when it comes to copy/assignment, as you don't really know when a copy will be made, due to the optimizations a compiler may use.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; March 29th, 2010 at 11:34 PM.
Bookmarks