Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在非虚拟析构函数的情况下自动调用父析构函数?_C++_Destructor - Fatal编程技术网

C++ 在非虚拟析构函数的情况下自动调用父析构函数?

C++ 在非虚拟析构函数的情况下自动调用父析构函数?,c++,destructor,C++,Destructor,我有一个在第三方代码中定义的结构。因为它是C代码,所以不定义虚拟析构函数。(在我的例子中,它是来自win32 appi的重叠结构) 我正在修改的客户代码有一个类S,派生自类a,派生自结构O struct O{}; class A : public O{}; class S : public A{}; 它们都没有将析构函数声明为virtual 如果在指向O的指针上调用delete,则会发生泄漏。当然 但是,如果在一个S指针上调用“代码>删除”,C++标准是什么状态? 它是否会自动调用两个父类的析

我有一个在第三方代码中定义的
结构。因为它是C代码,所以不定义
虚拟析构函数
。(在我的例子中,它是来自win32 appi的重叠结构)

我正在修改的客户代码有一个
类S
,派生自
类a
,派生自
结构O

struct O{};
class A : public O{};
class S : public A{};
它们都没有将析构函数声明为
virtual

如果在指向
O
的指针上调用
delete
,则会发生泄漏。当然

<>但是,如果在一个S指针上调用“代码>删除<代码>”,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 * pS = new S;
delete S; // would this call the parent destructor?
对。
除了析构函数可能是一个微不足道的不做任何事情的析构函数之外。

当然,派生类析构函数的每次调用都会导致所有父类的析构函数调用。但是,如果删除的类是指向没有虚拟析构函数的基类的指针,则不会调用派生类析构函数(可能是资源泄漏)


当然,派生类析构函数的每次调用都会导致所有父类的析构函数调用。但是,如果删除的类是指向没有虚拟析构函数的基类的指针,则不会调用派生类析构函数(可能是资源泄漏)

如果在指针的S?< /P >上调用删除,C++标准会说明什么? 根据[class.dtor](N4296中的§12.4/8)规定,其内容如下:

在执行析构函数体并销毁在该体中分配的任何自动对象之后 类
X
的析构函数调用
X
的直接非变量非静态数据成员的析构函数,即析构函数 对于
X
的直接基类,如果
X
是派生最多的类(12.6.2)的类型,则其析构函数调用
X
的虚拟基类的析构函数

因此在本例中,我们调用
~S()
,然后调用
S
的直接基类(
A
)的析构函数,然后调用这些基类(
O
)的析构函数

析构函数的
虚拟-ness只会以相反的顺序起作用,即:

O* s = new S;
delete s;
在这种情况下,只调用
~O()
——因为没有非静态数据成员、直接基类或虚拟基类,所以无需其他操作

如果在指针的S?< /P >上调用删除,C++标准会说明什么? 根据[class.dtor](N4296中的§12.4/8)规定,其内容如下:

在执行析构函数体并销毁在该体中分配的任何自动对象之后 类
X
的析构函数调用
X
的直接非变量非静态数据成员的析构函数,即析构函数 对于
X
的直接基类,如果
X
是派生最多的类(12.6.2)的类型,则其析构函数调用
X
的虚拟基类的析构函数

因此在本例中,我们调用
~S()
,然后调用
S
的直接基类(
A
)的析构函数,然后调用这些基类(
O
)的析构函数

析构函数的虚拟-ness只会以相反的顺序起作用,即:

O* s = new S;
delete s;

在这种情况下,只调用
~O()
——因为没有非静态数据成员、直接基类或虚拟基类,所以没有其他事情可做。

并且父级的内存也应该被释放?@StephaneRolland;是的,只要你有指向最派生对象的指针,一切都正常。父对象的内存也应该被释放?@StephaneRolland;是的,只要有指向最派生对象的指针,一切正常。请指定标准引用的来源。在不同版本的标准中,段落编号是不同的。@cheers-sandhth.-Alf确实需要一种标准的方式,以便引用标准。也许是一些自动导入的新标记?那太酷了。请指定标准报价的来源。在不同版本的标准中,段落编号是不同的。@cheers-sandhth.-Alf确实需要一种标准的方式,以便引用标准。也许是一些自动导入的新标记?那太酷了。