5

我听说空的析构函数不做任何事情并且调用它不会删除对象。但在代码中:

#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 detected * /.app: double free or corruption (fasttop):” 然后是“ABORT”。

如果重要的话,我启用了 c++11 标志。那么空构造函数实际上是做什么的呢?它做了一些事情,而我读到它没有。

4

3 回答 3

10

您的析构函数可能看起来是空的,但它实际上是在破坏成员变量。在这种情况下,它正在破坏myset,因此后续insert(20)崩溃。

如果你的类没有非 POD 成员变量,那么空的析构函数将真的什么都不做。

于 2013-02-06T19:28:43.317 回答
6

您的问题提到了几个不同的问题。

首先,有错误消息。“双重释放”可能是因为析构函数被调用了两次:一次由您调用,一次由 C++ 运行时调用,此时变量不再在范围内(在main函数的右大括号处)。

其次,关于空析构函数没有删除对象的问题。实际上,它不会从内存中删除对象,但会破坏其成员变量。因此,在您手动调用析构函数后,内存object仍然被分配,但myset不再有效。

于 2013-02-06T19:34:18.127 回答
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

如您所见,不需要手动调用。

于 2013-02-06T19:30:16.027 回答