8

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

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

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

4

2 回答 2

6

尽管返回类型 inDerived可以与基类型共同变体,但您不能对参数类型做同样的事情。即,覆盖函数应如下所示:

class Derived : public Base 
{ 
public: 
    const Derived& operator+ (const Base&) const; 
}; 
于 2012-10-21T14:18:29.623 回答
3

这种重载对于普通的抽象类是不可能的。第一:你应该将+声明为非成员重载运算符作为成员函数还是非成员(朋友)函数?.

如果你真的需要这个功能,你能得到的最好的方法是从模板接口继承:

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,马丁

于 2012-10-21T14:33:40.900 回答