Use*_*400 5 c++ operator-overloading matrix
就像我之前的许多程序员一样,我正在试着用C++编写通道矩阵类.我从未做过非常严重的运算符重载,这导致了问题.基本上,通过单步执行
这就是我所说的导致问题的原因.
cMatrix Kev = CT::cMatrix::GetUnitMatrix(4, true);
Kev *= 4.0f;
cMatrix Baz = Kev;
Kev = Kev+Baz; //HERE!
Run Code Online (Sandbox Code Playgroud)
根据调试器似乎正在发生的事情是添加了Kev和Baz,但随后该值丢失,当重新分配给Kev时,内存只是其默认的狡猾值.如何重载我的运算符以允许此语句?我的(精简版)代码如下.
//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;
}
Run Code Online (Sandbox Code Playgroud)
Seb*_*ian 10
您的运算符+和*必须按值返回,而不是按引用返回.您将通过引用返回临时变量.此外,当参数应为const引用时,您的参数将按值传递:
cMatrix cMatrix::operator+(cMatrix const& m)
{
cMatrix matrix(*this);
matrix += m;
return matrix;
}
cMatrix cMatrix::operator*(float f)
{
cMatrix matrix(*this);
matrix *= m;
return matrix;
}
Run Code Online (Sandbox Code Playgroud)
你应该看看Boost.Operators.这将让你实现只operator*=和operator+=并自动提供正确的实现operator+和operator*.
PS:如果您只是为了学习体验而实现矩阵类,请不要犹豫,看看像Matrix模板库这样的其他实现.
PPS:如果您不想使用boost,或者您只是想了解最佳实践,请查看Boost.Operator并执行他们的操作.
IMO规范形式的重载添加是这样的:
class X {
public:
X& operator+=(const X& rhs) { /*add rhs to *this*/ }
};
inline X operator+(X lhs, const X& rhs) {lhs+=rhs; return lhs;}
Run Code Online (Sandbox Code Playgroud)
这同样适用于-,*,/,如适用.
请注意,+返回副本,而不是引用.这很重要,因为它A+B创建了一个新值,因此它无法返回对现有值的引用.
此外,它是一个免费的功能.IMO最好实现二元运算符的那些,它们既可以作为成员实现,也可以作为自由函数实现,如果它们对称地处理它们的操作数(如同+),作为成员函数,如果它们不对称地处理它们的操作数( as +=,更改其左参数.如果实现operator+为成员,则必须创建function const(X operator+(const X& rhs) const),以便可以为左侧的常量元素调用它.
| 归档时间: |
|
| 查看次数: |
1693 次 |
| 最近记录: |