当类的指针实例超出范围时不调用析构函数是真的吗?



以以下代码为例:

  class MyClass
   {
   public:
  ~MyClass()
   {
     cout << "Destructor calledn";
    }
   };
  int main()
   {
      MyClass Testvar;
      //  destructer called for this
      MyClass *ptrvar;
      ptrvar = &Testvar;
      // but not for this
   }

它给我带来了很多困惑。上面的代码输出:析构函数调用只有一次。我在main中声明了两个MyClass实例,其中一个是MyClass类型的普通变量,另一个是指向普通变量的相同类型的指针。这里不需要析构函数(不需要动态分配),但为了便于示例,我在类中定义了一个析构函数。因此,由于定义了两个类实例,因此应该调用析构函数两次。但当我运行这段代码时,这不会发生。如果我删除指针并定义一个普通实例,程序打印:

析构函数调用析构函数叫做

我的观察是,当指针实例超出作用域时,不会隐式调用析构函数。我是对的还是漏掉了什么

我在main

中声明了两个MyClass实例

不你没有。您声明了MyClass的一个实例,并创建了一个指向该实例的指针。就是这样。

你的代码的行为是正确的。

我的观察是,当指针实例超出作用域时,不会隐式调用析构函数。我是对的,还是漏掉了什么?

这是正确的。c++不提供垃圾收集器。你必须自己记录你的指针。您可以使用智能指针来实现。

您只创建了一个对象,并且只为该对象调用析构函数。

指针不实例化另一个对象,它只是指向前一个对象

在堆栈上分配的对象超出作用域以及动态创建的对象(使用operator new)被显式销毁(operator delete)时调用析构函数

您实际上只实例化了一个类型为MyClass的对象。发生在这一行:

MyClass Testvar;

在下一行中,您只声明了一个指向MyClass类型对象的指针,但这并没有创建一个新对象:

MyClass *ptrvar;

在这一行中,您将第一个MyClass的地址分配给指针:

ptrvar = &Testvar;

所以指针指向同一个对象,你仍然只有一个MyClass的实例。当作用域关闭时,TestVar被删除,析构函数被调用一次。

您可以创建一个新的MyClass对象(在堆上),并将其地址分配给指针,如下所示:

MyClass *ptrvar = new MyClass();

现在您确实有两个MyClass对象。但是,当范围关闭时,您仍然只会看到一个对象被删除。这是因为new在堆上而不是在堆栈上创建对象,并且这些对象不会在创建它们的作用域结束时自动删除。您必须使用delete:

手动执行此操作
delete ptrvar;

执行这一行时,您将看到析构函数被调用。如果你不这样做,你就把你的对象留在堆上,并且"泄露"了它所占用的内存。

为了避免手工完成所有这些工作,您应该使用c++提供的内置智能指针

最新更新