2014-09-04 46 views
0

你覺得這一塊的C++代碼的內容:是使用新OK隱式向下轉換嗎?

Polygon* p; 
if(shape=="Rectangle") 
    p = new Rectangle(); 
else if(shape=="Triangle") 
    p = new Triangle(); 
else 
    exit(EXIT_FAILURE); 

,其中矩形和三角形從基類派生的多邊形。

它背後的想法是,我需要使用派生類中的特定方法,直到程序運行時才知道我需要哪個類。 有沒有更好的方法來做到這一點?它編譯但我不知道是否調用了所選派生類的析構函數,以便正確釋放特定變量。

附屬問題:dynamic_cast操作是否涉及數據複製?

謝謝:)

編輯:

感謝您對所有這些非常有啓發性的答案。

現在讓我們假設方法

bool isIsosceles() 

在三角,但不是在矩形實現。

然後調用馬上

p->isIsosceles() 

顯然會失敗。

我的第一個想法是,要麼:

聲明和實現在基類多邊形isIsosceles()虛擬方法

virtual bool isIsosceles() 
{ 
    cout << "Isosceles means nothing to me." << endl; 
    exit(EXIT_FAILURE); 
} 

或在if語句中使用的dynamic_cast的。

這些選項中的任何一個都是很好的做法嗎?

非常感謝

+0

_「有沒有更好的方法做這件事?」是的,使用智能指針而不是用'new()'和'delete'自己進行內存管理。此外,我會建議將此代碼放入指定的工廠類中,這是負責創建正確的類型。 – 2014-09-04 16:01:37

+0

'dynamic_cast'不涉及數據拷貝,但它確實涉及使用運行時間類型信息(RTTI)。它通常被認爲是一個緩慢的操作。 – YoungJohn 2014-09-04 16:14:20

回答

1

如果你還記得delete pPolygon析構函數是virtual會工作。這是至關重要的。

更好的選擇是將其包裝在智能指針中。

0

這不是向下轉換。您實際上在此處使用多態,即創建一些派生類型的對象,您將使用它作爲其基本類型的對象。

你可以做到這一點,但與你用new分配的所有東西一樣,使用delete。另外要注意的是,你需要一個虛擬的析構函數中Polygon,像:

class Polygon { 

    virtual ~Polygon(); 
} 

否則你將與對象切片結束了,這是你將有對象「半已刪除」。

附加說明:僅供參考,向下轉換是,使用類,執行以下操作:

Polygon* polygon = new Triangle(); 

Triangle* triangle = dynamic_cast<Triangle*>(polygon); 

// Check that we effectively had a triangle under this polygon pointer 
if(triangle){ 
    //do something with the triangle 
} 
1

是隱式的向下轉換使用新的OK?

這裏沒有「downcasting」:這是一個直接使用多態行爲。你的Polygon *是一個指向基類的指針;您的構建代碼會生成一個通過使用虛擬成員函數來抽象實現的對象。

它編譯,但我不知道是否調用所選派生類的析構函數,以便正確釋放特定變量。

只要在基類的析構函數是虛擬的(應該是)通過基類指針釋放對象將盡一切正常:

delete p; 

是否有更好的辦法這樣做?

您可以使用std::unique_ptr<Polygon>自動執行刪除Polygon對象的過程。當指針超出範圍時,使用智能指針會破壞對象。

dynamic_cast操作是否涉及數據複製?

我假設你沒有爲dynamic_cast這裏使用,因爲Polygon聲明虛成員函數感興趣所有操作。但是,當您執行dynamic_cast時,沒有數據複製正在進行。系統會檢查是否允許投射,並且可以爲您提供正確的投射指針,或返回nullptr

0

其背後的想法是,我需要使用派生類中的特定方法,直到程序運行時才知道我需要哪個類。

這種失敗了多態性的目的,它允許您執行操作,而無需知道您正在使用的派生類型。

有沒有更好的方法來做到這一點?

這取決於你實際上想要完成什麼。例如,您所展示的內容可以作爲類工廠的一部分來實現。如果你沒有在創建它們之後展示你如何使用這些對象,那麼很難說你是否做對了。

我不知道是否調用了所選派生類的析構函數,以便正確釋放特定變量。

只有在~Polygon()被宣佈爲virtual時纔會有效。

沒有一個dynamic_cast的操作涉及數據複製?

編號A dynamic_cast只是執行運行時查找以獲取指向同一對象的VMT的不同部分的指針。