在抽象基类中重载运算符的正确方法是什么? [英] What is the proper way to overload operators in abstract base classes?

查看:20
本文介绍了在抽象基类中重载运算符的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Suppose I have an abstract base class, that just defines a container on which addition can be performed:

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

然后我希望 Base 的子类提供实际操作:

Then I want subclasses of Base to provide the actual operation:

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

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

Here is my problem: operator+() is supposed to return a new Base object, but Base being abstract it won't compile.

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

I tried to get around that by using a factory to return a reference to a Base object, but then in the body of the operator I find myself doing casts, because the addition only makes sense on Derived objects.

总之,感觉就像是在咬自己的尾巴,有什么好的解决办法吗?

In any case, it feels like I am biting my own tail, is there a proper solution to this?

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

UPDATE: Based on the answers so far, it seems I am using the wrong pattern. I want to separate the interface from the implementation, so that library code only has to know the interface and client code provides the implementation. I tried to do that by providing the interface as an abstract base class, and the implementation as subclasses.

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

UPDATE2: My question was actually 2 questions, a concrete one (about overloading operators in abstract classes) and another about my intent (how do I allow the client to customize the implementation). The former has been answered: don't. For the latter, it seems that the Interface Class pattern I use is actually a good one to solve that problem (according to Griffiths and Radford), it's just that I should not mess with overloaded operators.

推荐答案

最好的事情是不要.

operator+ 返回一个值,根据定义,您不能返回抽象类型的值.只为具体类型重载运算符,避免从具体类型继承,以防止被重载运算符切片".

operator+ returns a value and you can't return a value of an abstract type, by definition. Overload the operators only for concrete types and avoid inheriting from concrete types to prevent "slicing by overloaded operator".

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

Overload symmetric binary operators like operator+ as free functions and you can control which combinations of types can be sensibly combined, and conversely prevent the combination of objects of types for which the combination doesn't make sense.

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

If you have a valid way of performing an "add" via two base class references and creating a new object you will have to return via a pointer, reference or pointer-wrapping smart object. Because you can't preserve the conventional semantics of + I would recommend using a named function, e.g. Add() instead of making an operator+ with a "surprising" syntax.

这篇关于在抽象基类中重载运算符的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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