怎样在抽象类中声明重载运算符,并在派生的非抽象类中重写呢?(How do I declare an

2019-08-01 17:03发布

我试着写一个抽象类,一些纯虚二元操作,应该由派生类,以实现运营商多态性实现。 这里有一个简单的例子:

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();
}

它不会对现在的运营商做什么无所谓,重要的部分是它返回什么:它返回一个临时的派生对象,或者对它的引用。 现在,如果我尝试编译,我得到这样的:

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中的唯一的纯虚函数)被重写? 衍生为什么应该是抽象的呢?

Answer 1:

这种超载是不可能在一个干净的方式正常的抽象类。 第一:你应该申报+非会员超载运营商成员函数或非成员(朋友)的功能? 。

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

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_trick和http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

HTH,马丁



Answer 2:

尽管在返回类型Derived可以共同变种的基地之一,你不能这样做与参数类型相同。 即,最重要的功能应该是这样的:

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


文章来源: How do I declare an overloaded operator in an abstract class and override it in a derived non-abstract class?