我读到的每个地方,如果没有定义析构函数,编译器仍会创建一个析构函数。那么明确定义一个是什么意思?
谢谢
答案 0 :(得分:7)
编译器提供的默认值可能无法完成您需要完成的所有操作。例如,如果您有动态分配的内存需要delete
d,则必须自己定义析构函数。编译器不会为你做那件事。
答案 1 :(得分:4)
如果您需要在析构函数中执行某些操作。
例如,您可能需要释放内存或关闭文件句柄。
答案 2 :(得分:4)
明确定义C ++析构函数的意义在于生成的C ++析构函数无法正确执行资源管理工作。例如
class Example {
MyType* m_pValue;
Example() {
m_pValue = new MyType();
};
当然C ++在这里定义了一个析构函数,但这个析构函数做了什么?真的没什么。我需要它做的是释放类所拥有的内存。为此,我需要自己的
~Example() {
delete m_pValue;
}
注意:对于这种情况,虽然您可能想要使用auto_ptr<T>
之类的,但我出于演示目的而避免使用
答案 3 :(得分:0)
因此,您可以明确清理您的实例。如果你分配(新)内存,那么你必须释放它。
答案 4 :(得分:0)
隐式析构函数可能无法完成所有操作。可能存在数据库连接,文件处理程序等需要明确关闭的资源。
答案 5 :(得分:0)
空显式析构函数的另一个重要情况是从基类派生时。 基类应始终具有虚拟析构函数,否则由于内存泄漏,您将接近很多问题。
答案 6 :(得分:0)
隐式析构函数只会通过调用析构函数来销毁属于该类成员的对象。如果在销毁这些对象时需要进行任何特殊的额外处理,编译器将不会知道它,因此在销毁对象之前不会调用这些函数。
此外,如果您正在使用非RAII代码,则可能需要在对象本身可以完全关闭之前释放内存,文件句柄,其他操作系统对象等资源。
还有一个特殊情况,你需要提供析构函数的实现,即当你编写一个被设计为基类并因此具有虚析构函数的类时。一旦明确声明了析构函数(虚拟与否无关),编译器就不会生成隐式析构函数。所以在这种情况下,你必须提供析构函数的定义,即使它是空的。
答案 7 :(得分:0)
显式构造函数和析构函数在实现RAII(资源获取是初始化)时非常有用。很可能在不使用析构函数的情况下释放资源,但是有一些丑陋的问题,例如:如果在释放资源之前抛出异常将会发生什么。
在构造函数中使用资源获取任务并在析构函数中释放资源是确保资源在应用时释放的简单方法。
答案 8 :(得分:0)
我在IO类中使用显式析构函数来确保正确关闭所有文件(HDF,NetCDF,ASCII /二进制文件)。我不认为默认的编译器生成的析构函数会为你做这件事。