如何在抽象类中声明重载运算符,并在派生的非抽象类中重写它? [英] How do I declare an overloaded operator in an abstract class and override it in a derived non-abstract class?

查看:189
本文介绍了如何在抽象类中声明重载运算符,并在派生的非抽象类中重写它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用一些纯虚拟二进制操作符编写一个抽象类,应该由派生类实现,以完成操作符多态性。这里有一个简单的例子:

I'm trying to write an abstract class with some pure virtual binary operators, which should be implemented by the derived class in order to accomplish operator polymorphism. Here's a simplified example:

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对象,或者一个对它的引用。现在,如果我尝试编译,我得到这个:

It doesn't matter right now what the operator does, the important part is what it returns: it returns a temporary Derived object, or a reference to it. Now, if I try to compile, I get this:

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也是抽象的?

What's wrong? Isn't operator+ (the only pure virtual function in Base) being overriden? Why should Derived be abstract as well?

推荐答案

这种重载是不可能与一个普通的抽象类以干净的方式。首先:您应该将+声明为非成员将操作符重载为成员功能还是非成员(朋友)功能?

This kind of overloading is not possible with a normal abstract class in a clean way. First: you should declare + as non member Overload operators as member function or non-member (friend) function?.

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

The best you can get is to inherit from a templated interface if you really need this functionality:

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&运算符+ =(Foo const& foo){你会得到一个编译器错误,说运算符没有实现。如果您想了解有关查找原理的更多信息,请访问 http://en.wikipedia。 org / wiki / Barton%E2%80%93Nackman_trick http://en.wikipedia.org / wiki / Curiously_recurring_template_pattern

If you comment out Foo& operator+=(Foo const& foo){ you will get a compiler error saying that the operator is not implemented. If you want to know more about the principles involved lookup http://en.wikipedia.org/wiki/Barton%E2%80%93Nackman_trick and http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

HTH,Martin

HTH, Martin

这篇关于如何在抽象类中声明重载运算符,并在派生的非抽象类中重写它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆