我想在C ++上创建一个很好的接口,每个实现都需要在其上定义添加。
我想做这样的事情:
class A{
...
virtual A& operator+(const A& other) =0;
...
}
// this is my interface or abstract class.
class B : A{
...
B& operator+(const B& other);
...
}
// this is the kind of implementation i would like. a B element can be added by another B element only ! At least this the constraint I am aiming at.
由于c ++不接受逆变,我的函数B& operator+(const B& other)
没有实现virtual A& operator+(const A& other)
。这样做的方法有点棘手(但有点干净......)吗?
答案 0 :(得分:7)
template<class Y>
class A
{
virtual Y& operator+=(const Y& other) = 0;
};
class B : A<B>
{
// must implement B& operator+=(const B& other) else B is abstract
};
是一种方式。这个习惯用法在实施政策时很常见。见http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
答案 1 :(得分:5)
您尝试做的事情在任何语言都是不可能的,因为它没有意义。
在某些语言中,方法类型中的方法是逆变的,但是如果它接受超类型,则意味着该方法是一个重载。即operator+(const A&)
会超载operator+(const B&)
。但不是相反。因为当你有两个A实例(我们称之为x
和y
)并写x + y
时,将调用该方法,编译器无法知道两者是否相同子类型,因为该信息仅在运行时可用。所以在运行时是唯一可以检查的时间。
所以:
+
(如果它不是多态的,它必须是模板)并且编译器在未定义时会发出婊子。您可以编写concept check class以尽早找到并避免使用太深的模板扩展堆栈时出现错误。