什么时候类必须在C++;课堂,为什么? 什么时候,类必须在C++类中定义析构函数,为什么?< /P> 刚刚开始在C++中学习这一点,需要澄清。 如果你的类需要做特殊清理,比如释放动态分配的内存,只需要定义析构函数。 < P>当你动态分配内存时,你需要定义析构函数。一个很好的经验法则是,如果在任何构造函数中使用new,则可能需要析构函数。任何不是自动存储或静态存储的内容都被认为是动态分配的

什么时候类必须在C++;课堂,为什么? 什么时候,类必须在C++类中定义析构函数,为什么?< /P> 刚刚开始在C++中学习这一点,需要澄清。 如果你的类需要做特殊清理,比如释放动态分配的内存,只需要定义析构函数。 < P>当你动态分配内存时,你需要定义析构函数。一个很好的经验法则是,如果在任何构造函数中使用new,则可能需要析构函数。任何不是自动存储或静态存储的内容都被认为是动态分配的,c++,destructor,C++,Destructor,属于清理类别的任何内容都适合放入析构函数,例如关闭网络连接,可能还有其他原因,但我想到的第一个原因是,可能需要显式释放某些类属性 如果您的类只有两个int属性,那么当您调用delete myObject时,这些属性将与对象一起自动删除。但是,如果它包含任何动态分配的属性,这些属性将不会随对象一起释放,因此您需要在析构函数中明确删除它们。如果析构函数的默认行为不是您想要的,则只需定义析构函数 销毁对象时,析构函数会执行以下操作,无论您是否定义自定义析构函数: 调用每个数据成员的析构函数 调用每个

属于清理类别的任何内容都适合放入析构函数,例如关闭网络连接,可能还有其他原因,但我想到的第一个原因是,可能需要显式释放某些类属性


如果您的类只有两个int属性,那么当您调用
delete myObject
时,这些属性将与对象一起自动删除。但是,如果它包含任何动态分配的属性,这些属性将不会随对象一起释放,因此您需要在析构函数中明确删除它们。

如果析构函数的默认行为不是您想要的,则只需定义析构函数

销毁对象时,析构函数会执行以下操作,无论您是否定义自定义析构函数:

  • 调用每个数据成员的析构函数
  • 调用每个基的析构函数
这实际上可以处理您可能想做的大多数事情。在构造函数中分配内存时,通常定义自定义析构函数:

struct A {
    B *b_ptr;

    A() : b_ptr(new B) { }
    ~A() { delete b_ptr; }
};
但是当您使用标准容器和智能指针时,需要自定义析构函数的情况相对较少。例如,如果您有这样一个类

struct A {
    std::unique_ptr<B> b_ptr;

    A() : b_ptr(new B) { }
};
因为当输入流成员被销毁时,
输入流
将自动关闭

有时候,你需要做一些特别的事情。您需要一个特殊的调用来获取或释放资源。在这种情况下,您需要一个析构函数:

struct C {
    ResourceHandle resource_handle;
    C() : resource_handle(resouce_manager.acquireResource()) { }
    ~C() { resource_manager.releaseResource(resource_handle); }
};
但是,您尽可能地将这种行为本地化,这样就不必在许多类中重复。例如,您可能希望使类如下所示:

struct ResourceHolder {
    ResourceHandle resource_handle;
    ResourceHolder() : resource_handle(acquireResource()) { }
    ~ResourceHolder() { releaseResource(resource_handle); }
};

现在,您只需在每个需要这些资源之一的类中使用ResourceHolder,就不必再次重复获取和释放逻辑。

析构函数不仅用于释放分配的内存,例如构造函数中的内存

您可以通过使用析构函数来实现功能

利用此功能的类型示例:

std::fstream
关闭打开的文件

std::lock\u guard
解锁互斥锁


std::shared_ptr
递减参考计数器,或在计数器为0时释放内存。

有两个实例需要定义析构函数:

struct C {
    ResourceHandle resource_handle;
    C() : resource_handle(resouce_manager.acquireResource()) { }
    ~C() { resource_manager.releaseResource(resource_handle); }
};
<>你在你的类中分配资源,也考虑复制构造函数和赋值运算符,你可能需要定义它们,即使是为了防止它们被使用。
  • 该类将从派生。在这种情况下,析构函数必须是虚拟的。原因是,如果使用指向父类的引用或指针对派生类进行析构函数,而父类包含派生类的实例,则不会调用派生类的析构函数
    或者,如果它是从中继承的,则需要虚拟析构函数,这是最常见的情况,但不是唯一的情况。您可能还希望在析构函数中关闭您的类管理的网络连接。@celtschk对于初学者来说,我认为这已经足够好了,我认为joe不需要担心网络连接yet@celtschk我还说需要,,虽然关闭析构函数中的连接可能是合适的,但您也可以在删除它之前调用close方法,“唯一的时间”是错误的和误导性的。没有必要对其他案例进行详细说明,但是声称它们不存在是错误的。即使您有一个特殊的关闭方法,您仍然希望在析构函数中关闭它。例如,如果由于异常而调用析构函数,则很可能没有调用close方法。除非它们由智能指针处理(应该是这样)。此问题的工作量太大,可能会重复。这不是一个完全重复的问题,但是任何人问这个问题都会通过学习三的规则来学习他们应该知道的。我不认为这是一个坏问题,当然是一个初学者的问题,但至少它不是一个主观问题