2011-04-26 181 views
3

如果我有一個基類和一個派生類,並且我在父虛擬中析構函數delcare,但是實例化一個類型爲子類的對象,當它被銷燬時它會調用父析構函數的權利(因爲虛擬)?如果我還在派生類中聲明瞭析構函數,它是否會調用析構函數(基類和派生類)。提前致謝 :-)。C++虛擬析構函數

我的問題的第二部分是關於第一部分。爲什麼基類析構函數需要聲明爲虛擬的。不要考慮循環式的結構。他們不分享同一個名字,那麼對它的需求在哪裏?它不應該像destrucotrs一樣工作,或者默認情況下只有一個被稱爲?也可以通過後期綁定來檢測所有的類和對象是由什麼組成的?

編輯:我的問題不只是關於虛擬析構函數,但爲什麼它需要被聲明爲虛擬的,因爲它們都應該被默認調用。

+1

嗯,你的第一段回答第二個。這在任何體面的C++語言書中都有介紹。並在*相關*部分的權利的問題。 – 2011-04-26 04:42:19

+1

[虛擬析構函數如何工作?](http://stackoverflow.com/questions/2722537/how-do-virtual-destructors-work) – 2011-04-26 04:42:52

+0

@Hans,我有一本書,它不包括在所有。 – rubixibuc 2011-04-26 04:44:51

回答

8

是的,父析構函數會自動調用。

應該對析構函數進行虛擬化,以便派生實例可以被認爲具有對基類實例的引用的代碼正確銷燬。

非常有限的情況下,它是確定不能虛擬化,如果你真的需要節省虛函數表查找幾個週期。

+0

是否將virtual關鍵字以不同方式應用於析構函數和複製構造函數?因爲它是同一個想法的一部分,所以我要求副本構造者。使用memeber函數,您可以擁有的唯一區別是該類的返回類型。所有參數和功能名稱必須相同。這些其他函數(析構函數複製ctors)如何在運行時表示?他們是否都有相同的名字,或者他們是按順序? Sry提出所有問題,只是想真正理解它: - /。 – rubixibuc 2011-04-26 04:54:57

+0

基本上,在繼承層次結構中聲明析構函數高於所有析構函數,即使名稱不同? – rubixibuc 2011-04-26 04:56:51

+0

是的。構造函數和析構函數名稱不像常規方法名稱;特殊的classname :: classname和classname ::〜classname語法告訴編譯器它是一個構造函數或析構函數,所以繼承查找構造函數/析構函數,而不是特定的類名 – 2011-04-26 05:05:29

4

虛擬析構函數的需要是因爲多態性。如果您有類似以下內容:

class A { ... }; 

class B : public A { ... }; 

void destroy_class(A* input) 
{ 
    delete input; 
} 

int main() 
{ 
    B* class_ptr = new B(); 
    destroy_class(class_ptr); //you want the right destructor called 

    return 0; 
} 

雖然有點做作的例子,當你刪除傳入的指針爲destroy_class()功能,你要正確的析構函數被調用。如果class A的析構函數未被聲明爲virtual,那麼只會調用class A的析構函數,而不是class B的析構函數或任何其他派生類型的class A

像這樣的東西通常是非模板多態數據結構等的事實,其中單個刪除函數可能必須刪除某些基類類型的指針,該指針實際上指向派生類型。

2

rubixibuc,

呀子類的析構函數首先被調用,那麼它的超類......那麼它的父類,依此類推,直到我們到達對象的析構函數。

更多這裏:http://www.devx.com/tips/Tip/13059 ...這是值得的閱讀......只有一個屏幕滿,但它是一個INFORMATIVE屏幕全。