2011-07-19 25 views
0

我們知道需要虛擬析構函數。運行時多態的構造函數行爲

Base *bptr = new Derived(); 
delete bptr; 

如果一個派生類對象是由一個基類指針和當對象超出範圍指出,只有基類的析構函數被調用,除非析構函數是虛擬的。

我想知道在這種情況下構造函數是如何正確工作的。 由於Base指針指向Derived對象,因此只有Base構造函數應該被調用。它如何正確調用派生類的構造函數。

請解釋一下背後的原因。

+0

「如果派生類對象被基類指針指向,並且對象超出作用域,則只有基類析構函數被調用,除非析構函數是虛擬的。」 - 如果派生類的對象超出範圍,則派生類析構函數被調用,並且任何其他正常指針的存在和類型都是不相關的。如果一個正常的指針指向任何東西超出範圍,則不會調用任何東西。智能指針可以調用析構函數,在這種情況下,虛擬調度的確是必需的,以確保它是派生類的派生類。 'new X'雖然沒有範圍。 –

+0

感謝您的更正。實際上,我的意思是說,當「刪除bptr」被執行時,只有基類析構函數被調用,除非析構函數是虛擬的。 – user166002

回答

2

在用new創建對象時,我們有完整信息的對象;

new Derived(); // static type is same as dynamic type 

您分配指針的LHS部分是無關緊要的。這就是爲什麼你不需要這種構造函數的機制。有關更多信息,請參閱Bjarne Stroustrup的頁面。

其他說明,virtual需要析構函數,因爲您正在使用指向delete對象的指針。

delete bptr; // static type may not be same as dynamic type 
2

new Derived()在任何地方都沒有基類引用。你可以選擇甚至把它分配給什麼。因此,得到的指針分配給什麼不會影響構造。

2

當您執行以下操作:

Base *bptr = new Derived(); 

要調用的new運營商爲Derived類,因爲這是你正在構建什麼。

當您將new返回的Derived*指定給Base*時,您只需上傳指針,該指針是隱式操作。

0

明確地說要構建的Derived一個實例:

Base *bptr = new Derived(); 

手段請構造一個對象,如果類型class Derived,然後請一個指針存儲到該對象bptr。所以編譯器有沒有什麼可猜測或推斷

new Derived(); 

創建的class Derived和泄漏該對象的對象:

與它比較。編譯器在這裏也沒什麼可猜測或推論的。這兩個片段之間的唯一區別是前者存儲指針,後者不存在。

相關問題