我创建了一个复数类、定义的运算和一些函数,如 arg、模数等。我还将虚数单位i定义为命名空间中的常量。问题是它z = i + 2
不会返回任何错误并且可以正常工作,但编译器不接受z = 2 + i
表示操作数在int
and之间无效的行const complex
。
我应该怎么做才能以两种方式定义操作?
我创建了一个复数类、定义的运算和一些函数,如 arg、模数等。我还将虚数单位i定义为命名空间中的常量。问题是它z = i + 2
不会返回任何错误并且可以正常工作,但编译器不接受z = 2 + i
表示操作数在int
and之间无效的行const complex
。
我应该怎么做才能以两种方式定义操作?
您应该实现整数和复数之间的转换或定义两个运算符:
complex operator+(int a, const complex& b)
和
complex operator+(const complex& a, int b)
你应该为你的班级超载complex operator+(int lhs, const complex& rhs);
。使它成为一个friend
函数,以便您传入两个参数。
作为为运算符提供实数和复数重载的替代方法:如果为complex
类提供转换构造函数(未标记explicit
且可以采用单个参数的构造函数),则它可以将实数隐式转换为复数:
class complex
{
public:
complex(double real, double imag = 0) : real_(real), imag_(imag) {}
double real() const { return real_; }
double imag() const { return imag_; }
private:
double real_;
double imag_;
};
然后您可以定义operator+
为采用两个complex
参数,编译器将为您转换int
为complex
:
complex operator+(const complex& a, const complex& b)
{
return complex(a.real() + b.real(), a.imag() + b.imag());
}
现在,当编译器遇到此代码时,它会识别出存在complex, complex
for 的重载,operator+
并且2
可以隐式转换为complex
:
z = 2 + i;
有两种方法可以为类重载运算符:作为成员函数和作为......以及非成员函数。Complex
当在运算符的左侧(在这种情况下)有一个类的对象(在这种情况下是类)时,会创建第一个对象+
。非成员函数用于不发生上述情况的情况。在这种情况下,两个操作数都被指定了,重载的操作符本身只是偶然(有时)在类内部以朋友访问权限创建的(事实上,如果您不访问私有成员,则不需要它。将它包含在内部的另一个原因class 是这样,给定类的运算符在同一个地方)。
class Complex {
public:
// more things...
Complex operator+(int i); // cx + 1
friend Complex operator+(int i, const Complex &cx); // 1 + cx
// more things...
};
Complex Complex::operator+(int i)
{
Complex complexCopy( *this );
complexCopy.sum( i );
return complexCopy;
}
Complex operator+(int i, const Complex &cx)
{
Complex complexCopy( cx );
complexCopy.sum( i );
return complexCopy;
}
请记住,您需要重载复制构造函数,以防您在构造函数中分配任何资源。
希望这可以帮助。
处理运算符重载的一个好方法+
是从+=
.
class complex {
double real
double imag;
complex& operator+=( complex const& other ) {
real += other.real;
imag += other.imag;
return *this;
}
complex& operator+=( double other ) {
real += other.real;
return *this;
}
};
然后编写非成员运算符以使用上述成员运算符:
inline complex operator+( complex left, double right ) {
return left+=right;
}
inline complex operator+( double left, complex right ) {
return right+=left;
}
inline complex operator+( complex left, complex const& right ) {
return left+=right;
}
请注意,我至少complex
按值取了一个参数——考虑到我要返回一个complex
数字,我也可以这样做。
这个计划的一个好处是二元运算符是真正的样板,工作是在成员+=
运算符中完成的。
在 C++11 中,您可以更进一步,自动编写上述所有运算符,其中它根据operator+=
. 但这只有在编写大量重载类时才值得+
。