【问题标题】:missing destructor declaration缺少析构函数声明
【发布时间】:2014-02-01 01:09:57
【问题描述】:

如果我忘记在 C++ 类中声明析构函数,谁能告诉我对象的内存会发生什么?我的意思是,它是否被释放或导致内存泄漏? 示例或演示将不胜感激。

提前致谢。

【问题讨论】:

  • 这取决于你的班级。举个例子。

标签: c++ memory destructor


【解决方案1】:

如果没有声明析构函数,编译器会生成析构函数,它会调用对象所有成员的析构函数。只有在使用原始内存(C 文件、内存分配等)时才会发生泄漏。

【讨论】:

    【解决方案2】:

    这取决于类的数据成员。如果类管理资源,那么它需要一个析构函数来释放它们(您还应该提供一个复制构造函数和赋值运算符,或者使该类不可复制和不可分配)。

    如果类有内置的数据成员,或者管理自己资源的数据成员,那么隐式生成的析构函数就足够了。它将调用所有数据成员的析构函数。

    【讨论】:

      【解决方案3】:

      为任何重要的类定义析构函数通常被认为是一种很好的做法(请参阅Rule of Three)。然而,在现代 C++(即 C++11 及更高版本)中,它不再像以前那样必要了。

      如果您的类不是从其他任何东西继承的,则任何直接成员(例如变量和对象)都将被编译器提供的默认析构函数正确销毁。同样,如果您的对象拥有任何包装在智能指针中的堆分配对象,它们也会被安全地销毁。

      如果您的对象通过原始指针拥有任何堆分配的数据,则会出现问题。隐式析构函数无法知道如何处理它们,因此您需要自定义析构函数来清除它们。例如:

      class MyClass
      {
          int m_data1;
          std::string m_data2;
          std::shared_ptr<Widget> m_data3;
          Widget *m_data4;
      };
      

      在上面的示例中,成员 m_data1m_data2m_data3 都将在没有自定义析构函数的情况下正确清除。但是,m_data4 指向的对象将不会自动清除。如果它是由MyClass 分配的,那么它通常会导致内存泄漏(除非它被其他东西释放)。

      综上所述,继承以一种重要的方式改变了事物。如果你的类被其他任何东西继承,那么你应该总是给它一个虚拟析构函数。如果您的对象是通过指向继承类的指针删除的,并且该类没有具有虚拟析构函数,则永远不会调用子类的析构函数,从而可能导致内存泄漏。

      例如:

      class Parent
      {
      public:
          Widget m_data1;
      }
      
      class Child : public Parent
      {
      public:
          Widget m_data2;
      }
      
      int main()
      {
          Parent *ptr = new Child;
          delete ptr; // <-- clears-up Parent but not Child
      }
      

      在上面的例子中,ptrParent 类型,所以delete 只知道对象的Parent 部分。这意味着只有m_data1 会被正确清除。如果没有虚拟析构函数,它不知道对象的Child 部分,因此m_data2 将不会被正确清除(永远不会调用它的析构函数)。

      【讨论】:

        猜你喜欢
        • 2021-04-07
        • 1970-01-01
        • 2017-12-14
        • 1970-01-01
        • 1970-01-01
        • 2013-03-14
        • 2021-11-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多