【问题标题】:Destructors in inheritance继承中的析构函数
【发布时间】:2013-03-07 19:27:11
【问题描述】:

当我浏览下面的代码时,我有疑问。即为什么即使派生类的对象超出以下代码的范围,也不调用派生类的析构函数:

#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;

class ClassA
{
    protected:
        int width, height;
    public:
      void set_values(int x, int y)
      {
        width = x;
        height = y;
      }
      virtual int area()
      {
        return 0;
      }
      ~ClassA()
      {
         cout << "base class destructor called" << endl;
      }
 };

class ClassB : public ClassA
{
      public :
   int area()
   {
     return (width * height);
   }
   ~ClassB()
       {
      cout << "derived class destructor called" << endl;
   }
 };


 int main()
 {
   ClassA *Ptr = NULL;
   ClassB Obj;
   Ptr = &Obj;
   Ptr->set_values(10, 20);
   cout << Ptr->area() << endl;
   delete Ptr;
     return 0;
 }

【问题讨论】:

    标签: c++ inheritance destructor


    【解决方案1】:

    你不应该在指向派生类对象的基类指针上调用delete,除非基类析构函数是virtual,否则你得到的是Undefined Behavior

    基类中的析构函数需要标记为virtual

    virtual ~ClassA(){}
    

    【讨论】:

    • 即使析构函数是虚拟的,在指向局部变量的指针上调用delete也是仍然未定义的行为。
    • @SteveJessop:没错!我错过了
    • @Steve : 那么我们不应该删除指针,只是我们已经声明并使用它...?
    • @nagaradderKantesh:只有在有 new 时才调用 delete,否则不会调用。你所拥有的是一个指向本地/自动对象的指针。当声明对象的范围{ } 结束时,自动对象会自动销毁。它不需要显式释放。
    • @Alok Save:那么如果我没有删除指针,它仍然会保存导致内存泄漏的对象的地址 na ..?
    【解决方案2】:

    在基类中创建你的析构函数virtual。否则,它会调用 base 的析构函数。

    class ClassA
    {
    // ...
          virtual ~ClassA()
          {
             cout << "base class destructor called" << endl;
          }
    };
    

    【讨论】:

    • 是的,我知道..但是在删除 ptr 基类析构函数后将调用然后控制返回并且超出程序意味着它超出范围(派生类对象'Obj'将超出scope ) 但是即使派生类对象 Obj 超出了作用域范围,为什么没有调用派生类的析构函数。
    • @nagaradderKantesh:“然后控制返回”——你调用了未定义的行为。你不能说接下来控制在哪里,因为如果任何地方都有未定义的行为,那么整个程序的行为就是未定义的。
    猜你喜欢
    • 2021-04-13
    • 2012-04-28
    • 1970-01-01
    • 2011-12-27
    • 2011-12-31
    • 2016-08-14
    • 2011-10-14
    • 2012-11-14
    • 2011-11-24
    相关资源
    最近更新 更多