我想知道默认类析构函数在被调用时是否实际执行了任何操作。
我一直在研究它,我发现如果我创建一个带有调用自己的析构函数的函数的类,它根本不做任何事情(即所有变量保持不变,实例仍然存在且可用)
这是否意味着类析构函数可以被认为是所有类都具有的继承虚函数,并且可以重新定义它(删除指针等并清除成员变量)但是如果它没有重新定义它什么都不做?
如果是这样,析构函数本身不能用作“清除所有数据”类型的函数,并通过清除动态内存分配变量并重新使用它而不是让计算机到达而使代码的某些部分更有效在堆上找到一个新的内存块?
感谢。
答案 0 :(得分:2)
答案 1 :(得分:2)
我一直在研究它,我发现如果我创建一个带有调用自己的析构函数的函数的类,它根本不做任何事情(即所有变量保持不变,实例仍然存在且可用)
考虑以下代码:
#include <iostream>
struct A
{
~A()
{
std::cout << "A::~A" << std::endl;
}
};
struct B
{
A a;
};
int main()
{
B b;
std::cout << "Calling b.~B()" << std::endl;
b.~B();
std::cout << "Done" << std::endl;
}
You'll see调用B
的默认析构函数调用A
的析构函数,因为B
包含A
:
Calling b.~B()
A::~A
Done
A::~A
只有当b
超出范围时,堆栈才会被解除,合并的B::~B()
会被调用,反过来,A::~A()
会被释放。
答案 2 :(得分:1)
除了Notinlist的回答:
默认构造函数调用基类的构造函数。
如果是这样,析构函数本身不能用作“清除所有数据” 一种功能,使代码的某些部分更有效率 清除动态内存分配变量并重新使用它 而不是让计算机在上面找到新的内存块 堆?
您有点描述内存池。如果需要,您的对象可以从您创建的某个池系统中获取内存缓冲区并将其返回。但是,在大多数情况下,分配足够快且不经常,以至于人们不再常见(不再)这样做。并不是说它们很少发生,但它们需要发生很多以注意到性能损失。
答案 3 :(得分:1)
手动调用析构函数通常是一个坏主意。关于destructors的C ++ FAQ部分有很多关于此的信息。
如果您确实想要显式地销毁对象,可以使用其他范围来安全地调用析构函数(请参阅此常见问题解答entry)。此方法还会阻止您使用已销毁的对象实例。虽然实例似乎可以使用,但实际上并非如此。
如果您打算释放某个类实例所拥有的部分资源,而不是全部资源,那么您可以尝试两件事:
clear()
(或类似)方法。clear()
后保持类的不变量。假设您手动调用析构函数的初始方法有效,或者您选择执行类似上述clear()
方法的操作,在这两种情况下,您可能会在以后遇到问题。
C ++中一个经过充分理解和经常实践的资源管理方法是资源获取初始化(通常缩写为RAII,但如果令人困惑则忽略该名称,这个概念是可以理解的)。有关有用的信息,请参阅this维基百科文章或此answer。
这是tl; dr虽然:
遵循这个习惯用法通常会在C ++资源管理出现之前阻止它们。