[英]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類存在並不意味着你將永遠使用它。 如果我有一個帶有子類Circle
和Rectangle
的Shape
類,我也有一個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.