How do I go about overloading C++ operators to allow for chaining?
- by fneep
I, like so many programmers before me, am tearing my hair out writing the right-of-passage-matrix-class-in-C++. I have never done very serious operator overloading and this is causing issues. Essentially, by stepping through
This is what I call to cause the problems.
cMatrix Kev = CT::cMatrix::GetUnitMatrix(4, true);
Kev *= 4.0f;
cMatrix Baz = Kev;
Kev = Kev+Baz; //HERE!
What seems to be happening according to the debugger is that Kev and Baz are added but then the value is lost and when it comes to reassigning to Kev, the memory is just its default dodgy values. How do I overload my operators to allow for this statement?
My (stripped down) code is below.
//header
class cMatrix
{
private:
float* _internal;
UInt32 _r;
UInt32 _c;
bool _zeroindexed;
//fast, assumes zero index, no safety checks
float cMatrix::_getelement(UInt32 r, UInt32 c)
{
return _internal[(r*this->_c)+c];
}
void cMatrix::_setelement(UInt32 r, UInt32 c, float Value)
{
_internal[(r*this->_c)+c] = Value;
}
public:
cMatrix(UInt32 r, UInt32 c, bool IsZeroIndexed);
cMatrix( cMatrix& m);
~cMatrix(void);
//operators
cMatrix& operator + (cMatrix m);
cMatrix& operator += (cMatrix m);
cMatrix& operator = (const cMatrix &m);
};
//stripped source file
cMatrix::cMatrix(cMatrix& m)
{
_r = m._r;
_c = m._c;
_zeroindexed = m._zeroindexed;
_internal = new float[_r*_c];
UInt32 size = GetElementCount();
for (UInt32 i = 0; i < size; i++)
{
_internal[i] = m._internal[i];
}
}
cMatrix::~cMatrix(void)
{
delete[] _internal;
}
cMatrix& cMatrix::operator+(cMatrix m)
{
return cMatrix(*this) += m;
}
cMatrix& cMatrix::operator*(float f)
{
return cMatrix(*this) *= f;
}
cMatrix& cMatrix::operator*=(float f)
{
UInt32 size = GetElementCount();
for (UInt32 i = 0; i < size; i++)
{
_internal[i] *= f;
}
return *this;
}
cMatrix& cMatrix::operator+=(cMatrix m)
{
if (_c != m._c || _r != m._r)
{
throw new cCTException("Cannot add two matrix classes of different sizes.");
}
if (!(_zeroindexed && m._zeroindexed))
{
throw new cCTException("Zero-Indexed mismatch.");
}
for (UInt32 row = 0; row < _r; row++)
{
for (UInt32 column = 0; column < _c; column++)
{
float Current = _getelement(row, column) + m._getelement(row, column);
_setelement(row, column, Current);
}
}
return *this;
}
cMatrix& cMatrix::operator=(const cMatrix &m)
{
if (this != &m)
{
_r = m._r;
_c = m._c;
_zeroindexed = m._zeroindexed;
delete[] _internal;
_internal = new float[_r*_c];
UInt32 size = GetElementCount();
for (UInt32 i = 0; i < size; i++)
{
_internal[i] = m._internal[i];
}
}
return *this;
}