19

我计划创建一个接口(而不是 C++ 中的虚拟基类),其方法采用自己类型的参数。

class Base {
public:
    virtual void seriousMethod(const Base &arg) = 0;
}

然而,派生类不应接受基类类型的参数,而是派生类类型的参数。

class Derived: public Base {
public:
    virtual void seriousMethod(const Derived &arg) { /* ... */ }
}

我怎么会意识到这一点?我必须模板基类(例如Base<Derived>)还是有更清洁的解决方案?

4

1 回答 1

19

你不能直接这样做。想想这个案例:

Base b;
Derived d;
Base& d_ref = d;
d_ref.seriousMethod(b);  // What happens here?

在编译时,变量d_ref是静态类型Base的,所以根据 的定义Base,应该可以将其b作为参数seriousMethod

但是在运行时,动态类型d_refDerived,所以根据 的定义Derived,它不能b作为参数seriousMethod。它无法转换b为,Dervied因为它可能是一个直接Base对象(如果Base不是抽象的),或者它可能是从Base它派生的一些其他类,与Derived.

您假设唯一真正的解决方法是奇怪地重复出现的模板模式是正确的,即模板化Base和定义Dervied为:

class Derived : public Base<Derived> { ... }

这消除了上面说明的问题,因为每个派生自的类型Base<T>都有一个不同的基类,并且不会通过继承相互关联。

于 2013-09-07T07:56:38.717 回答