我计划用一个接受自己类型参数的方法创建一个接口(而不是c ++中的虚拟基类)。
class Base {
public:
virtual void seriousMethod(const Base &arg) = 0;
}
但是,派生类不应该是基类类型的参数,而是派生类类型的参数。
class Derived: public Base {
public:
virtual void seriousMethod(const Derived &arg) { /* ... */ }
}
我怎么会意识到这一点?我是否必须模拟基类(例如Base<Derived>
)或者是否有更清洁的解决方案?
答案 0 :(得分:15)
你不能直接这样做。想想这个案子:
Base b;
Derived d;
Base& d_ref = d;
d_ref.seriousMethod(b); // What happens here?
在编译时,变量d_ref
具有静态类型Base
,因此根据Base
的定义,它应该能够将b
作为参数到seriousMethod
。
但在运行时,动态类型d_ref
为Derived
,因此根据Derived
的定义,它不能将b
作为参数seriousMethod
。它无法将b
转换为Dervied
,因为它可能是直的Base
对象(如果Base
不是抽象的),或者它可能是从Base
派生的其他类{1}}与Derived
不同。
你是正确的,假设唯一真正的方法就是奇怪的重复模板模式,即模板化Base
并将Dervied
定义为:
class Derived : public Base<Derived> { ... }
这消除了上面说明的问题,因为从Base<T>
派生的每个类型都有一个不同的基类,并且不会通过继承相互关联。