簡體   English   中英

在派生類中重新定義typedef?

[英]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中重新定義,並且也沒有編譯(它也非常混亂)。

我也無法從同一個基類派生蘋果和橘子,以返回BaseDerived中父類的指針/引用。 我需要物理返回對象的實例。

  1. 有什么辦法可以聲明抽象typedef嗎?
  2. 如果沒有,是否有任何其他解決方案可以實現我想要做的事情?

首先,看看這個語法:

fruit func() override { return Orange(); }

什么是override 在C ++ 03中,沒有這樣的關鍵字。 它只在C ++ 11中。 因此,請確保您使用的是知道此關鍵字的編譯器。

其次,在衍生類中, fruit確實是Orange 重新定義typedef不是問題。 問題是, OrangeApple不是協變型。 從另一個中獲取將使它們變得協變。 在您的情況下,您必須從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)之間的主要區別之一。)

有很多方法可以解決這個問題。 首先,讓我們假設AppleOragne有一個名為Fruit的公共基類。 一種解決方案是使用new動態分配對象並返回Fruit -pointer。

另一個解決方案,您的函數可以采用指針或引用Fruit,而不是返回值,然后可以填充。

另一個解決方案是擁有某種容器對象,內部可容納Apple或Orange。 這樣你就可以退貨了。

報告的錯誤告訴您所需的一切。 這意味着Derived方法中返回的類型需要從base方法中返回的類型派生。

這樣,如果虛擬調用基本方法,則可以將返回的對象視為基本方法返回的對象。

實際上,您需要返回一個指針或引用來執行此操作。

您需要做的是定義一個新的Fruit基類,並從中派生出AppleOrange

然后讓func()返回Fruit*

這將使您確定在某些時候確保Fruit*delete的問題。

有了更多的上下文,我懷疑(可能很薄)模板是你所追求的解決方案,而不是繼承。

暫無
暫無

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

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