c++ - 在抽象基类中重载运算符的正确方法是什么?

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

假设我有一个抽象基类,它只定义了一个可以在其上执行加法的容器:

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

然后我想要Base的子类来提供实际的操作:

class Derived: public Base {
public:
    Base operator+(const Base& rhs) { // won't compile
        // actual implementation
    }
};

这是我的问题:operator+() 应该返回一个新的 Base 对象,但 Base 是抽象的,它不会编译。

我试图通过使用工厂返回对 Base 对象的引用来解决这个问题,但随后在运算符的主体中我发现自己在进行强制转换,因为添加仅对 Derived 对象有意义。

总之,感觉自己是在咬自己的尾部,请问有什么好的解决办法吗?

更新:根据目前的答案,我似乎使用了错误的模式。我想将接口(interface)与实现分开,这样库代码只需要知道接口(interface),而客户端代码提供实现。我试图通过提供作为抽象基类的接口(interface)和作为子类的实现来做到这一点。

更新 2:我的问题实际上是 2 个问题,一个是具体的(关于在抽象类中重载运算符),另一个是关于我的意图(我如何允许客户自定义实现)。前者已回答:不要。对于后者,似乎我使用的接口(interface)类模式实际上是解决该问题的好方法(根据 Griffiths and Radford ),只是我不应该乱用重载运算符。

最佳答案

最好不要。

operator+ 返回一个值,根据定义,您不能返回抽象类型的值。仅对具体类型重载运算符并避免从具体类型继承,以防止“通过重载运算符进行切片”。

operator+ 之类的对称二元运算符重载为自由函数,您可以控制哪些类型的组合可以合理地组合,并反过来阻止组合没有意义的类型的对象组合.

如果您有通过两个基类引用执行“添加”并创建新对象的有效方法,您将必须通过指针、引用或指针包装智能对象返回。因为您不能保留 + 的常规语义,所以我建议使用命名函数,例如Add() 而不是使用“令人惊讶”的语法制作 operator+

关于c++ - 在抽象基类中重载运算符的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4867430/

相关文章:

c++ - 多态 lambda 的非类型模板参数?

c++ - 如何获取模板模板参数的模板参数?

c++ - 是否可以编译具有在编译时无法解析的外部依赖项的静态库?

unordered_map 中 operator[] 的 C++ 特化

perl - '*{}' 似乎是一个有效的 Perl5 解引用运算符(perldoc : overload). 它解引用了什么?

c++ - 为什么要创建一个只有一个成员的类,即 operator()?

C++对象多态性问题

从 void * 转换时的 C++ 多态性问题

c++ - Linux 中的线程状态

c++ - 从 C++ 中的文件加载数据时出现段错误