[英]Redefining a typedef in derived class?
因此,經過大量搜索我的問題的答案后,我終於放棄了我的Google技能。
我有一個基類Base和一個派生類Derived 。 我想在Derived類中使用一個類重寫Base類中的類型。 這是一個例子:
class Apple {
public:
Apple() { }
// ...
};
class Orange {
public:
Orange() { }
// ...
};
class Base {
public:
typedef Apple fruit;
// ...
virtual fruit func() { return Apple(); }
};
class Derived : public Base {
public:
typedef Orange fruit;
// ...
fruit func() override { return Orange(); } // <-- Error C2555!
};
這段代碼不起作用,它給出了一個
C2555 error ('Derived::func': overriding virtual function return type differs and is not covariant from 'Base::func').
以上是我嘗試過的解決方案之一。 我也嘗試在Base中創建一個虛擬嵌套類,並在Derived中重新定義,並且也沒有編譯(它也非常混亂)。
我也無法從同一個基類派生蘋果和橘子,以返回Base和Derived中父類的指針/引用。 我需要物理返回對象的實例。
首先,看看這個語法:
fruit func() override { return Orange(); }
什么是override
? 在C ++ 03中,沒有這樣的關鍵字。 它只在C ++ 11中。 因此,請確保您使用的是知道此關鍵字的編譯器。
其次,在衍生類中, fruit
確實是Orange
。 重新定義typedef不是問題。 問題是, Orange
和Apple
不是協變型。 從另一個中獲取將使它們變得協變。 在您的情況下,您必須從Apple
派生Orange
才能使其正常運行。
請注意,您必須將fruit
的返回類型更改為fruit*
或fruit&
。
class Orange : public Apple {}; //correct - your code will work
class Apple : public Orange {}; //incorrect - your code will not work
這個想法是,在基類中,返回類型應該是基類型的指針/引用 (這是Apple
),並且在派生類中,返回類型可以是Apple
類型的指針/引用或從中派生的任何類。
順便問一下,這有意義嗎? 從Apple
那里獲取Orange
?
下面的課程設計怎么樣?
class Fruit {};
class Apple : public Fruit {};
class Orange : public Fruit {};
class Base
{
virtual Fruit* f();
};
class Derived : public Base
{
virtual Fruit* f();
};
無需使用typedef
。
這開始沒有多大意義。 Derived
應該可以在預期Base
任何地方使用,所以你應該能夠做到
Base *foo = new Base();
Apple x = foo->func(); // this is fine
Base *bar = new Derived();
Apple y = foo->func(); // oops...
我認為你需要研究一個不同的設計。 目前尚不清楚你的目標是在這里只是什么,但我猜你可能要么需要Base
是一個類模板用Fruit
作為模板參數,或者你需要得到完全擺脫繼承。
你不能真的這樣做,如果你有一個價值對象,你必須知道它是哪種類型。 (這是靜態類型語言(如C ++)和動態類型語言(如Ruby和Python)之間的主要區別之一。)
有很多方法可以解決這個問題。 首先,讓我們假設Apple
和Oragne
有一個名為Fruit
的公共基類。 一種解決方案是使用new
動態分配對象並返回Fruit
-pointer。
另一個解決方案,您的函數可以采用指針或引用Fruit,而不是返回值,然后可以填充。
另一個解決方案是擁有某種容器對象,內部可容納Apple或Orange。 這樣你就可以退貨了。
報告的錯誤告訴您所需的一切。 這意味着Derived
方法中返回的類型需要從base方法中返回的類型派生。
這樣,如果虛擬調用基本方法,則可以將返回的對象視為基本方法返回的對象。
實際上,您需要返回一個指針或引用來執行此操作。
您需要做的是定義一個新的Fruit
基類,並從中派生出Apple
和Orange
。
然后讓func()
返回Fruit*
。
這將使您確定在某些時候確保Fruit*
被delete
的問題。
有了更多的上下文,我懷疑(可能很薄)模板是你所追求的解決方案,而不是繼承。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.