簡體   English   中英

C ++ clone習語中協變返回類型的用處?

[英]Usefulness of covariant return types in C++ clone idiom?

通常的克隆習語使用協變返回類型:

struct Base {
    virtual Base* clone();
};

struct Derived : public Base {
    Derived* clone();
};

我已經讀過這樣的信息,即協變返回類型是C ++的后續添加,而較舊的編譯器可能不支持它們。 在這種情況下, Derived類必須聲明其clone成員函數以返回Base* 因為,大概我只是在使用這個習語時通過Base指針和/或引用來訪問Derived對象,聲明返回類型Derived*的真正用途/好處是什么?

另外,一個相關的問題:

我更喜歡使用智能指針來表達clone簽名的所有權轉移語義。 使用協變返回類型時,這是不可能的,因為auto_ptr<Derived>auto_ptr<Base>不協變。 (請注意,我不是在尋找關於智能指針使用的講座 - 這里僅以auto_ptr為例)。 那么在這種情況下,有沒有理由不讓Derived返回auto_ptr<Base> 是否有更好的方式來表達所有權轉移語義?

因為,據推測,我只是在使用這個成語時通過Base指針和/或引用來訪問Derived對象...

你認為錯了。 僅僅因為Base類存在並不意味着你將永遠使用它。 如果我有一個帶有子類CircleRectangleShape類,我也有一個Window類。 當我可以使用Rectangle時,我不打算使用Shape*作為窗口的位置和大小。

對於所有權轉讓,無論如何都不應該使用智能指針。 我知道你不想講課,但我不是說智能指針很糟糕,你不應該在clone()使用它們。 您不能首先轉讓沒有所有權的東西的所有權。 如果有人想要一個auto_ptr那么他們應該用克隆的原始指針構造它。 其他智能指針類型也是如此。

當你有一個指向Derived的指針並希望得到它的克隆時,它很有用:

Derived *ptr = ...;
Derived *clone = ptr->clone();

如果沒有協變返回類型,您必須進行顯式轉換:

Derived *clone2 = (Derived*)ptr->clone();

請注意, Derived可能是更多派生類的基類,在這種情況下它更有意義。

不幸的是, auto_ptr<Derived>auto_ptr<Base>不協變。 因此,在這種情況下,您必須從所有克隆函數返回相同的類型。

暫無
暫無

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

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