【问题标题】:What does empty destructor do?空析构函数有什么作用?
【发布时间】:2013-02-07 03:35:15
【问题描述】:

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

#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 标志。那么空构造函数实际上是做什么的呢?它有作用,而我读到它没有。

【问题讨论】:

  • 问题在于object.~a();不要手动调用析构函数。
  • 我不想做,我只想知道析构函数到底做了什么。
  • 基本上它会将对象的内存释放回系统。所有成员变量的析构函数也被这个代码在后面的感觉中调用。
  • @user1873947:析构函数销毁所有成员变量。您直接调用 dtor 的主要时间是与使用 Placement new 结合使用。
  • 添加一个 B 类作为您的成员变量,而不是设置。在 B 和 A 的构造函数/析构函数中使用 cout 看看到底发生了什么。

标签: c++ destructor


【解决方案1】:

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

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

【讨论】:

  • 也许吧。如果你的类有一个基类或虚函数,那么析构函数也可能会做一些事情。
  • 这就是我想知道的,它删除了成员变量。谢谢,我会接受的。
  • @JamesKanze:是的,但我假设 OP 已经知道那部分。他这里的例子没有继承。
  • @user1873947 它不会删除它们(这不是凯文写的);它会破坏它们。
  • @user1873947:詹姆斯说了什么。 “delete”指的是delete 运算符,它破坏对象,然后释放对象所在的内存。在这种情况下,您只是在破坏,这也是一件好事,因为您的对象在堆栈上而不是分配的在堆上。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    超出范围时调用析构函数。我强烈建议不要调用析构函数,然后尝试访问父类的成员或成员函数。由于您的类具有成员变量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

    如您所见,无需手动调用。

    【讨论】:

    • 是的,我就是这么说的,伙计。 “由于您的类具有成员变量 myset,因此在手动调用时会释放这些变量”
    猜你喜欢
    • 2023-03-10
    • 2013-02-01
    • 1970-01-01
    • 2011-05-28
    • 2010-10-12
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多