如何在抽象类中声明重载运算符并在派生的非抽象类中重写它?

时间:2012-10-21 14:10:39

标签: c++ polymorphism operator-overloading abstract-class

我正在尝试编写一个带有一些纯虚拟二元运算符的抽象类,它应该由派生类实现,以实现运算符多态性。这是一个简化的例子:

class Base {
public:
    virtual const Base& operator+ (const Base&) const = 0;
};

class Derived : public Base {
public:
    const Derived& operator+ (const Derived&) const;
};

const Derived& Derived::operator+ (const Derived& rvalue) const {
    return Derived();
}

现在运算符的作用并不重要,重要的部分是它返回的内容:它返回一个临时的Derived对象或对它的引用。现在,如果我尝试编译,我会得到这个:

test.cpp: In member function ‘virtual const Derived& Derived::operator+(const Derived&) const’:
test.cpp:12:17: error: cannot allocate an object of abstract type ‘Derived’
test.cpp:6:7: note:   because the following virtual functions are pure within ‘Derived’:
test.cpp:3:22: note:    virtual const Base& Base::operator+(const Base&) const

怎么了?是不是操作符+(Base中唯一的纯虚函数)被覆盖?为什么Derived也应该是抽象的?

2 个答案:

答案 0 :(得分:6)

尽管Derived中的返回类型可以与基本类型共同变化,但您不能对参数类型执行相同的操作。即,重写函数应如下所示:

class Derived : public Base 
{ 
public: 
    const Derived& operator+ (const Base&) const; 
}; 

答案 1 :(得分:2)

使用普通的抽象类无法以干净的方式进行这种重载。首先:您应该声明+为非成员Overload operators as member function or non-member (friend) function?

如果您确实需要此功能,那么您可以获得的最好的方法是从模板化界面继承:

template<typename T>
class AddEnabled {
  public:
    friend T operator+ (T const& left, T const& right) {
      return left+=right;
    }
};

现在你写了

class Foo: public AddEnabled<Foo>{
  Foo():mVal(0){
  }

  Foo& operator+=(Foo const& foo){
    mVal+=foo.mVal;
  }

 private:
  int mVal;
}

如果你注释掉Foo& operator+=(Foo const& foo){,你会收到编译错误,说明运算符没有实现。如果您想了解更多相关原则,请查看http://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trickhttp://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

HTH,马丁

相关问题