簡體   English   中英

協變返回類型和類型轉換

[英]Covariant return type and type conversion

s->duplicate()返回一個Box*類型的對象,但我收到一個錯誤,用Box*初始化它。 它看起來像是被轉換回Shape* 如果將協變返回類型轉換回基類指針,有什么意義?:

struct Shape
{
    virtual Shape* duplicate()
    {
        return new Shape;
    }
};

struct Box : Shape
{
    virtual Box* duplicate()
    {
        return new Box;
    }
};

int main()
{
    Shape* s = new Box;
    Box*   b = s->duplicate();
}

錯誤:

main.cpp:22:12: error: cannot initialize a variable of type 'Box *' with an rvalue of type 'Shape *'
    Box*   b = s->duplicate();
           ^   ~~~~~~~~~~~~~~
1 error generated.

盡管Box::duplicate 在運行時被調用(通過虛擬調度),盡管Box::duplicate 重寫Shape::duplicate (協變),雖然Box::duplicate 返回Box* ,你仍然會得到一個Shape*指針,因為你通過Shape*指針調用duplicate() ,而Shape*Shape::duplicate()的返回類型,編譯器只看到你調用Shape::duplicate ,而不是Box::duplicate

C ++無法動態選擇類型,因此這是它能做的最好的。 你的Box*Box::duplicate出路上自動轉換為Shape* 正如Barry所說,“它仍然需要在編譯時進行編譯,在編譯時我們所知道的是它返回一個Shape* ”。

然后,要再次將其設置為Box* ,您需要顯式地轉換它(使用static_castdynamic_cast ),因為不存在隱式下轉換。

[C++11: 10.3/7]: 重寫函數的返回類型應與重寫函數的返回類型相同,或者與函數類的協變相同。 [..]

[C++11: 10.3/8]:如果返回類型D::f從返回類型不同B::f ,在返回類型的類類型D::f應的點處完全聲明D::f或應為D類。 當重寫函數被調用為重寫函數的最終覆蓋時,其結果將轉換為(靜態選擇的)重寫函數 (5.2.2) 返回的類型 [..]

在標准文本中,下面是一個相關的例子。

關鍵是不要這樣做:

Box*   b = s->duplicate();

這顯然無法工作,因為Shape::duplicate()返回一個Shape* 相反,如果您直接在Box上調用duplicate() ,則接受Box*

Box* old = new Box;
Box* b = old->duplicate(); // OK! We know it's a Box

暫無
暫無

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

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