[英]How does the compiler handle base class destructor calls in the derived destructor?
出於好奇,我嘗試執行以下示例,以查看編譯器是否向我發出警告,而不是調用導致堆棧溢出的無限循環。 我認為也許有不同的行為,而不僅僅是調用正常的函數或方法。 但是事實並非如此。 有什么特別的解釋嗎?或者因為我使用this
運算符顯式地調用了基類的析構函數,所以它只是作為普通的函數調用處理嗎?
例:
class A {
virtual ~A();
};
class B : A {
virtual ~B() { this->~A(); }
};
@MM的評論擊中了它。 您要兩次調用析構函數。 這是未定義的行為,任何事情都可能發生,包括您觀察到的行為。
(實際上,這些析構函數調用中很可能會修改對象的vptr,這意味着后續的析構函數調用將不再轉到最派生的對象。但這只是一個猜測。)
正確的做法是不要手動調用析構函數。
派生類中的虛擬析構函數將始終首先以遞歸順序調用父類析構函數,這樣將調用最“祖先”的基類析構函數,然后調用第二最“祖先”的析構函數,以此類推。子級從父級繼承,父級從GrandParent繼承。 Child類的析構函數實際上將調用GrandParent的析構函數,然后是Parent的析構函數,然后是Child的析構函數。
實際上,您的派生類構造函數還以相同的遞歸順序調用其父類構造函數。 您必須想象派生類就像一個“蛋糕”:每個繼承實例都為您的對象添加了一層。 因此,Child類具有3層{GrandParent,Parent,Child},每層的構造/破壞都由相應的類處理。
您嘗試執行的操作將嘗試兩次調用父析構函數,這是個壞主意。 通常,除非您重載了new
運算符,否則不必顯式調用析構函數。 請參閱此答案以獲取更多詳細信息: 手動調用析構函數是否總是表明設計不好?
調用派生類虛擬析構函數會導致對基類析構函數的調用。 但反之則不然。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.