操作符只能以一种方式定义——c++



我创建了一类复数,定义了操作和一些函数,如arg,模数等。我还将虚单位 I 定义为命名空间中的常量。问题是z = i + 2没有返回任何错误并且正常工作,但编译器不接受z = 2 + i行,说intconst 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());
}

现在,当编译器遇到这段代码时,它将识别operator+complex, complex重载存在,并且2可以隐式地转换为complex:

z = 2 + i;

类有两种重载操作符的方法:作为成员函数和作为…非成员函数。第一个是在操作符(本例中为+)的左侧有一个类的对象(在本例中为Complex类)时创建的。非成员函数用于不发生上述情况的情况。在这种情况下,两个操作数都被指定,并且重载操作符本身只是偶然(有时)在类内部创建具有友元访问(实际上,如果不访问私有成员,则不需要重载操作符)。把它放在类内的另一个原因是,这样给定类的操作符就在同一个地方了。

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+=的各种重载提取有效类型。但是,只有在编写大量重载+的类时,才值得这样做。

最新更新