C++ 中的自定义析构函数 x 默认构造函数

Rom*_*man 0 c++ destructor class object

我有一个有四个成员的类,但我没有实现析构函数。如果我删除该对象,默认析构函数将删除这 4 个成员,对吧?如果我创建一个空白的自定义析构函数,它们都不会被删除?如果我创建一个只删除其中一个的自定义析构函数,其他三个也会被删除吗?

bol*_*lov 5

认真回答你的问题

我认为回答你的问题实际上对你没有帮助,因为你提出问题的方式对你没有帮助。但无论如何,这就是:

如果我删除该对象,默认构造函数将删除 4 个成员,对吧?

正确的

如果我创建一个空白的自定义析构函数,它们都不会被删除

不正确。但所有成员仍将被正确删除。

如果我创建一个只删除其中一个的自定义析构函数,那么其他三个也会被删除吗?

析构函数(或任何方法)不能合法地显式删除其自己的成员。

解决您的困惑

如果p是一个指针,那么当你这样做时,你delete p并不是删除指针p,而是删除 所指向的对象pp在那里告诉你什么对象需要删除。之后delete p p还活着。当然它指向无效内存,但它本身并没有被删除。您可以分配给它并使其指向其他内容。

让我们考虑一个具有 3 个成员的简单类:一个 float、一个 int 指针和一个std::vector对象:

struct X
{
   float f;
   int* p;
   std::vector<double> v;
};
Run Code Online (Sandbox Code Playgroud)

你的类的 3 个成员是:浮点型、指针和std::vector对象。这些成员始终会被析构函数正确销毁,无论您是否有用户定义的析构函数或隐式析构函数。总是!全体会员!没有例外。您不能以任何方式抑制或修改此行为。

因为f我认为没有什么可以解释的。

现在是有趣的部分:p这里您需要看到一个非常重要的区别:指针p(这是您的数据成员)和 指向的潜在 int 对象p。与任何其他数据成员一样,指针p将由析构函数正确处理。

但是指针所指向的对象会发生什么情况呢p?有几种情况:您的指针可能指向 int 对象、null、未初始化或指向无效地址。如果它指向一个 int 对象,它可能指向另一个类类型的子对象的 int 对象,它可能是数组中的元素,它可能是静态对象或具有自动存储持续时间的对象,也可能是由new.创建的 int 对象 如果它是由它创建的,new那么X类有责任删除它或不删除它,并且如果必须销毁它,可能会有一个复杂的决定(想想共享指针)。应该删除iffX所指向的对象iff拥有该指针的所有权并且应该实现适当的逻辑。pX

正如您所看到的,编译器不可能知道指向什么p以及是否X应该删除它。这就是为什么默认析构函数不执行此操作的原因。

同样v,析构函数(默认或用户定义的)将正确销毁v. 您现在可能在内部std::vector有一个自己的指针成员,但是:它的std::vector责任是销毁指针可能指向的数组,而不是X。这一切都是开箱即用的,X不需要做任何特别的事情。

你应该如何考虑

C++ 中有RAII原则,尽管它的名字很糟糕,但它是 C++ 中最重要的概念之一。基本上,如果您的类获取需要手动管理的资源,那么该类拥有该资源的所有权,并负责释放该资源。因此,如果您的类执行手动内存分配( new),那么它有责任调用相应的delete. 如果它通过虚拟获取资源resource_aquire(),那么它也负责调用伴随的资源resource_destroy()

另一个重要的原则是单一职责原则:如果您的类负责管理资源,那么该类应该只做那件事。