【发布时间】:2014-08-18 16:45:43
【问题描述】:
关于我构建的类以及它如何通过 C++ 中的运算符重载与内置类型交互,我遇到了一些我不理解的事情。作为我的问题的一个例子,下面是一个(不完整的)复数类:
class complex {
public:
complex(double real=0., double imag=0.) : _real(real), _imag(imag) {;}
~complex() {;}
complex& operator=(const complex &rhs) {
if(this!=&rhs) {
this->_real = rhs._real;
this->_imag = rhs._imag;
}
return *this;
}
complex& operator*=(const complex &rhs) {
this->_real = this->_real * rhs._real + this->_imag * rhs._imag;
this->_imag = this->_real * rhs._imag + this->_imag * rhs._real;
return *this;
}
const complex operator*(const complex &other) const {
complex result = *this;
result *= other;
return result;
}
protected:
double _real;
double _imag;
};
当我使用以下 main 调用此代码时:
int main(void)
{
complex a(1.,0.);
complex b;
b = a * 2.;
b = 2. * a;
return 0;
}
我得到“main.cpp”中倒数第二行的编译器错误:
错误:‘2.0e+0 * a’中的‘operator*’不匹配
但之前的行没有错误。如果我将违规行中的“2.0”转换为复合体,那么一切都很好。所以我的问题是,编译器如何/为什么知道在第一行将双精度转换为复数,但(似乎)想在第二行使用双精度版本的 operator*?
如果我可以派生一个类,比如 Real,它从 double 派生并添加如下内容:
const complex operator*(const double &other)
那么我认为这可行,但我知道我不能这样做(内置类型不能用作基类)。
谢谢!
@MikeSeymore 有一个很好的解决方案。添加一个非成员函数。我最终得到的是:
complex operator*(double lhs, complex const &rhs) {
complex result(lhs,0.);
return result*=rhs;
}
世界上一切都很好。谢谢迈克。
顺便说一句:关于非类重载的讨论Operator overloading outside class
【问题讨论】:
-
您的代码中没有收到大量针对
{;}的恼人警告吗?如果没有,请将警告级别提高一个档次。 -
可以去掉复制赋值运算符;它所做的正是隐式生成的。
-
@KonradRudolph:实际上(现在可能不再是这种情况了)我过去使用的一些编译器如果主体中没有代码实际上会出现问题。这已成为一种可能不再需要的习惯。
-
顺便说一句,当隐式定义做正确的事情时,您不应该定义特殊成员 - 析构函数、复制构造函数、复制和移动赋值。让编译器完成它的工作。
标签: c++