我听说空的析构函数没有做任何事情,调用它不会删除对象。 但在代码中:
#include <iostream>
#include <set>
class a
{
public:
~a()
{}
std::set <int> myset;
};
int main()
{
a object;
object.myset.insert(55);
object.~a();
object.myset.insert(20);
std::cout << object.myset.size();
}
我得到: “ * glibc检测到* /.app:双重免费或腐败(fasttop):”然后“ABORT”。
如果重要,我启用了c ++ 11标志。那么空构造函数实际上做了什么?它做了一些事情而且我没有看到它。
答案 0 :(得分:7)
你的析构函数可能看起来是空的,但它实际上是在破坏成员变量。在这种情况下,它会破坏myset
,因此后续的insert(20)
会崩溃。
如果你的类没有非POD成员变量,那么空的析构函数将真正无效。
答案 1 :(得分:6)
您的问题提到了几个不同的问题。
首先,出现错误消息。 “Double free”可能是因为析构函数被调用了两次:一次由你运行,一次由C ++运行时调用,当变量不再在范围内时(在main
函数的右括号中)。
其次,你的问题是空的析构函数没有删除对象。实际上,它不会从内存中删除对象,但它会破坏其成员变量。因此,在手动调用析构函数后,仍会分配object
的内存,但myset
不再有效。
答案 2 :(得分:1)
超出范围时会调用析构函数。我强烈建议不要调用析构函数,然后尝试访问父类的成员或成员函数。由于您的类具有成员变量myset
,因此在手动调用时会解除分配,因此会出现分段错误。
当您完全使用对象时,将析构函数视为“清理”。在任何情况下都不应该手动调用它。
伪代码:
class MyClass {
public:
MyClass() {
std::cout << "Constructor" << std::endl;
}
~MyClass() {
std::cout << "~Destructor" << std::endl;
}
}
int main(int argc, char** argv) {
MyClass myClass;
return 0;
}
你应该看到这个输出:
Constructor
~Destructor
如您所见,无需手动调用。