我有两节课 . 基类 Parent
和派生类 Child
. 类 Parent
具有返回其类类型的纯虚函数 . 如何在派生类中覆盖它?
class Parent
{
public:
virtual Parent* OverrideMe(Parent* func) = 0;
};
class Child : public Parent
{
public:
Child* OverrideMe(Child* func) override;
};
我试过了 Child* OverrideMe(Child* func) override;
但我最终得到的错误是它没有覆盖基类成员 .
4 回答
如果C具有完全协方差和逆变支持,则输入中的正确关系为 contravariant ,输出中为 covariant . 即:
这似乎有点不直观,但它确实有意义 . 如果您期望
Animal*
,您应该能够处理Animal*
(其中Dog*
符合条件)的任何内容 . 相反,如果您在Animal*
上执行某些操作,则只需要一个可以采用Animal*
的操作 - 并且在该前端需要Organism*
的操作 .请注意,如果输入为 co variant,则会破坏类型系统 . 考虑类似的事情;
如果允许
Dog::OverrideMe
采用Dog*
,则会失败 -Cat*
不是Dog*
!因此,允许采用Animal*
......或更通用的东西(例如Organism*
),因为所有这些都可以正常工作 .C确实 not 支持输入中的逆变,输出中只有 covariance . 所以你可以写:
要么:
但没有别的 .
函数参数的类型和函数的cv限定符必须相同 . 所以你可以使用
您没有覆盖此处,因为您的
OverrideMe
函数不会接受与您尝试覆盖的基类中的函数相同的参数:这种“闻起来很糟糕”,换句话说,你正在“破坏”正常的“任何对象都应该可以替换为任何其他对象” .
如果在基类中有接口函数,则该函数应在整个类层次结构中采用相同的类型 .
所以正确的是:
父* OverrideMe(Parent * func)覆盖;
(正如juanchopanza所说,你可以返回一个派生类型,但你确定父返回的值总是同一个类吗?对我来说,这看起来像是可能返回“任何派生对象”的函数类型,在哪种情况下,你要么撒谎,要么以“有趣的效果”结束
如果出于某种原因,在你的情况下这实际上并不“有效”,那么你可能不应该以这种方式使用继承 .