簡體   English   中英

覆蓋返回基本類型的函數

[英]Override function that return base type

我有兩節課。 基類Parent類和派生類Child Class 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; 但我最終得到的錯誤是它沒有覆蓋基類成員。

如果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*的操作在這方面有資格。

請注意,如果輸入的是共同的變體,這將打破類型系統。 考慮類似的事情;

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

如果Dog::OverrideMe被允許Dog* ,那將失敗 - Cat*不是Dog* 因此,允許使用Animal* ......或任何比它更通用的東西(例如Organism* ),因為所有這些都可以正常工作。

C ++ 具有逆變支持輸入,只有協方差輸出。 所以你可以寫:

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

要么:

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

但沒有別的。

函數參數的類型和函數的cv限定符必須相同。 所以你可以使用

Child* OverrideMe(Parent* func) override;

您沒有覆蓋此處,因為您的OverrideMe函數不會接受與您嘗試覆蓋的基類中的函數相同的參數:

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

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

這種“聞起來很糟糕”,換句話說,你正在“破壞”正常的“任何對象都應該可以替換為任何其他對象”。

如果在基類中有接口函數,則該函數應在整個類層次結構中采用相同的類型。

所以正確的是:

父* OverrideMe(Parent * func)覆蓋;

(正如juanchopanza所說,你可以返回一個派生類型,但你確定父返回的值總是同一個類嗎?對我來說,這看起來像是可能返回“任何派生對象”的函數類型,在哪種情況下,你要么撒謊,要么以“有趣的效果”結束

如果出於某種原因,在你的情況下這實際上並不“有效”,那么你可能不應該以這種方式使用繼承。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM