簡體   English   中英

在非虛擬析構函數的情況下自動調用父析構函數?

[英]Automatic calling of parent destructor in case of non-virtual destructor?

我有一個在第三方代碼中定義的struct O 由於它是C代碼,因此沒有定義virtual destructor (在我的情況下,這是win32 appi中的OVERLAPPED struct )。

我正在修改的客戶代碼具有一個class Sclass S源自class A ,而其源於struct O

struct O{};
class A : public O{};
class S : public A{};

他們沒有宣布自己的析構函數為virtual

如果有人在指向O的指針上調用delete ,則會泄漏。 當然。

但是,如果我曾經在指向S的指針上調用delete ,那么C ++標准規定了什么? 即使兩個父類都沒有聲明其析構函數是虛的,它會自動調用兩個父類的析構函數嗎? 會釋放父母的相對記憶區嗎?

S * pS = new S;
delete S; // would this call the parent destructor?

關於

S * pS = new S;
delete S; // would this call the parent destructor?

是。 除了析構函數可能是瑣碎的無所事事的析構函數。

如果我曾經在指向S的指針上調用delete,那么C ++標准規定了什么?

它來自[class.dtor](N4296中的第12.4 / 8節):

執行完析構函數的主體並銷毀主體中分配的所有自動對象后,類X的析構函數調用X的直接非變量非靜態數據成員的析構函數, X的直接基類的析構函數,以及如果X是最派生類的類型(12.6.2),則其析構函數調用X的虛擬基類的析構函數。

因此,在這種情況下,我們調用~S() ,然后將調用S的直接基類( A )的析構函數,然后依次調用這些基類( O )的析構函數。

析構函數的virtual性僅以相反的順序起作用,即:

O* s = new S;
delete s;

在那種情況下,僅調用~O() -因為沒有非靜態數據成員,直接基類或虛擬基類,所以沒有其他事情要做。

當然,對派生類析構函數的每次調用都將導致所有父類的析構函數調用。 但是,如果刪除的類是沒有虛擬析構函數的基類的指針,則不會調用派生類的析構函數(可能發生資源泄漏)

struct A {};
struct B : A {};
struct C : B {};

int main() {
    B* p = new C;
    // This will clean up A and B, but leak the resources of C
    delete p;
}

暫無
暫無

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

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