有人可以解释我操作员的错误:
Matrix3D Matrix3D::operator*(Matrix3D& m) {
Matrix3D ret;
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
ret._data[i][j]=0.0;
for(int k=0;k<4;k++) {
ret._data[i][j] += (this->_data[i][k]*m._data[k][j]);
}
}
}
return ret;
}
Matrix3D& Matrix3D::operator=(Matrix3D& m) {
if(this==&m) {
return *this;
}
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
this->_data[i][j] = m._data[i][j];
}
}
return *this;
}
Matrix3D Matrix3D::Rotation(double ax, double ay, double az) {
Matrix3D rotX;
Matrix3D rotY;
Matrix3D rotZ;
rotX(
1, 0, 0, 0,
0, cos(ax), -sin(ax), 0,
0, sin(ax), cos(ax), 0,
0, 0, 0, 1
);
rotY(
cos(ay), 0, sin(ay), 0,
0, 1, 0, 0,
-sin(ay), 0, cos(ay), 0,
0, 0, 0, 1
);
rotZ(
cos(az), -sin(az), 0, 0,
sin(az), cos(az), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
);
// Matrix3D ret;
// ret = rotX*rotY*rotZ;
// This doesn't work
// C:\(...)\Matrix3D.cpp|100|error: no match for 'operator=' in 'ret = Matrix3D::operator*(Matrix3D&)(((Matrix3D&)(& rotZ)))'|
// however this does work
Matrix3D ret = rotX*rotY*rotZ;
return ret;
}
如上面代码中所述,类似
Matrix3D ret;
ret = rotX*rotY*rotZ;
将导致
C:\(...)\Matrix3D.cpp|100|error: no match for 'operator=' in 'ret = Matrix3D::operator*(Matrix3D&)(((Matrix3D&)(& rotZ)))'|
编译错误,而类似
Matrix3D ret = rotX*rotY*rotZ;
将编译时没有任何警告或错误(不知道矩阵是否正确,还没有检查过......)。
答案 0 :(得分:8)
实际上,两个运营商都被错误地宣布。他们应该采用const
引用来允许接受rvalues。
Matrix3D Matrix3D::operator*(const Matrix3D& m) const
// ^^^^^ ^^^^^
// this too, since you're not
// changing the LHS during '*'.
Matrix3D& Matrix3D::operator=(const Matrix3D& m)
// ^^^^^
您会发现*
不适用于rotX*(rotY*rotZ)
。
Matrix3D ret = rotX*rotY*rotZ;
编译的原因是因为根本没有调用operator=
。它只是将Matrix3D的复制构造函数调用为乘法的结果。并且乘法有效,因为rotX * rotY * rotZ
被重写为
rotX.operator*(rotY).operator*(rotZ)
且rotY
和rotZ
都是左值,因此它们可以绑定到Matrix3D&
。
答案 1 :(得分:5)
operator*
和operator=
的正确声明:Matrix3D Matrix3D::operator* (Matrix3D const& m) const;
Matrix3D& Matrix3D::operator= (Matrix3D const& m);
operator=
接受Matrix3D&
虽然rotX*rotY*rotX
会导致 rvalue ,因此您无法绑定对它的引用。
要开展工作,operator=
应该接受Matrix3D const&
,Obj a = b
可以绑定到 lvalues 和 rvalues 。
即使看起来Obj::operator=
使用{{1}}也不是,但它会使用通常所说的 copy-constructor 。阅读更多相关信息here。
答案 2 :(得分:4)
将赋值运算符的签名更改为const-correct:
Matrix3D& Matrix3D::operator=(Matrix3D const & m)
// ^^^^^
在您的示例代码中,赋值运算符想要绑定到临时值,而临时值不能绑定到非常量引用。相比之下,由第二段代码调用的复制构造函数确实接受了const引用,因此没有错误。
答案 3 :(得分:1)
Matrix3D& Matrix3D::operator=(Matrix3D& m)
您请求右侧参数是l值。它必须是现有变量,不能是临时值。请考虑改为使用const Matrix3D& m
。
Matrix3D ret = rotX*rotY*rotZ;
有效,因为它根本没有使用operator=
,而是使用默认构造函数Matrix3D::Matrix3D(const Matrix3D&)
。