10

我试图验证我对 C++ 析构函数的理解。

如果我自己不编写一个,我已经读过很多次 C++ 提供了一个默认的析构函数。但这是否意味着如果我确实编写了一个析构函数,编译器仍然不会提供堆栈分配的类字段的默认清理?

我的直觉是,唯一理智的行为是所有类字段都被销毁,无论我是否提供自己的析构函数。在这种情况下,我读了很多次的声明实际上有点误导,可以更好地表述为:

“无论你是否编写自己的析构函数,C++ 编译器总是编写一个默认的类似析构函数的序列来释放你的类的成员变量。然后你可以通过定义你自己的析构函数来指定额外的释放或其他任务”

这个对吗?

4

3 回答 3

25

当在 C++ 中清理对象时,该语言将

  • 首先调用类的析构函数,然后
  • 调用类的所有字段的析构函数。

(这假定没有继承;如果有继承,则通过递归地遵循相同的过程来销毁基类)。因此,您编写的析构函数代码只是您想要执行的自定义清理代码,以及单个数据成员的正常清理代码。您不会以某种方式“丢失”那些被正常调用的对象的析构函数。

希望这可以帮助!

于 2013-11-09T03:36:24.363 回答
2

是的——你的对象中包含的任何对象都将作为销毁对象的一部分被销毁,即使/尽管你的析构函数没有做任何事情来销毁它们。

事实上,你的析构函数通常不会做任何事情来销毁对象中包含的对象。它通常做的是销毁通过对象中的某些东西远程拥有的对象(例如,指向对象的指针、网络或数据库连接的句柄等)

唯一常见的例外是如果您的对象包含某种类型的缓冲区,并且您已经使用放置new在该缓冲区中构造了一些东西。如果您使用 placement new,您通常也计划直接调用 dtor。[请注意,“常见”可能夸大了您看到/使用它的频率——这真的很不常见,但其他可能性要少得多。]

于 2013-11-09T03:49:19.253 回答
0

是的。即使您确实编写了析构函数,C++ 编译器也会创建一个序列。考虑以下代码:

class foo{
    int a;
}

编写一个 deallocates 的析构函数a,一个堆栈分配的变量......这是不可能的。因此,即使您编写自己的析构函数,C++ 编译器也必须生成一个析构函数来释放堆栈对象。

于 2013-11-09T03:42:31.100 回答