覆盖返回基本类型的函数

时间:2015-04-08 19:11:24

标签: c++ inheritance interface abstract-class pure-virtual

我有两节课。基类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 个答案:

答案 0 :(得分:3)

函数参数的类型和函数的cv限定符必须相同。所以你可以使用

Child* OverrideMe(Parent* func) override;

答案 1 :(得分:3)

如果C ++具有完全协方差和逆变支持,则输入中的正确关系逆变,输出中的协变。即:

struct Organism { };

struct Animal : Organism {
    virtual Animal* OverrideMe(Animal* ) = 0;
};

struct Dog : Aniaml {
    Dog* OverrideMe(Organism* ) override { ... }
    ↑↑↑             ↑↑↑↑↑↑↑↑
    covariant       contravariant
};

这似乎有点不直观,但它确实有意义。如果您期望Animal*,则应该能够处理Animal*Dog*符合条件的任何内容)。相反,如果您在Animal*上执行某些操作,则只需要一个可以执行Animal*的操作 - 并且需要Organism*的操作符合该前端的条件。

请注意,如果输入为 co <​​/ strong>变体,则会破坏类型系统。考虑类似的事情;

Animal* a = new Dog;
a->OverrideMe(new Cat);

如果允许Dog::OverrideMe使用Dog*,则会失败 - Cat*不是Dog*!因此,允许使用Animal* ...或更通用的内容(例如Organism*),因为所有这些都可以正常工作。

C ++ 支持输入中的逆变,输出中只有协方差。所以你可以写:

Dog* OverrideMe(Animal* ) override { ... }

或:

Animal* OverrideMe(Animal* ) override { .... }

但没有别的。

答案 2 :(得分:2)

你没有在这里覆盖,因为你的OverrideMe函数没有采用与你试图覆盖的基类中的函数相同的参数:

class Parent
{
    public:
        virtual Parent* OverrideMe(Parent* func) = 0;
};

class Child : public Parent
{
    public:
        virtual Child* OverrideMe(Parent* func) override;
};

答案 3 :(得分:0)

这“闻起来很糟糕”,换句话说,你正在“破坏”正常的“任何对象都应该可以替换为任何其他对象”。

如果在基类中有接口函数,则该函数应在整个类层次结构中采用相同的类型。

所以正确的事情是:

父* OverrideMe(Parent * func)覆盖;

(正如juanchopanza所说,你可以返回一个派生类型,但你确定父返回的值总是同一个类吗?对我来说,这看起来像是可能返回“任何派生对象的函数类型” “,在这种情况下,你要么撒谎,要么结束”有趣的效果“)

如果出于某种原因,在你的情况下这实际上并不“有效”,那么你可能不应该以这种方式使用继承。