首页 > 解决方案 > 在 C++ 中调用析构函数不会手动销毁对象

问题描述

我想在 C++ 中显式调用对象的析构函数来销毁该对象。

这只是一个简单的程序来试验编程语言的特性。我有一个将内部数据成员设置为 1 的默认构造函数,以及将内部数据成员设置为参数的重载构造函数,以及一个显示刚刚销毁对象的内部数据成员的析构函数。还有一个打印内部数据成员的功能。

#include <iostream>
using std::cout;
using std::endl;

class myClass {
  public:
   myClass()
   {
     i = 1;
     cout << "default ";
     cout << "constructor called with " << this->i << endl;
   }

   myClass(int i)
   {
     this->i = i;
     cout << "constructor called with " << this->i << endl;
   }

   ~myClass()
   {
     cout << "object " << i << " destroyed!" << endl;
   }

   void printData()
   {
     cout << "object's data is " << i << endl;
   }
  private:
   int i;  // private data member
};

int main() {
  myClass a;
  myClass b;
  myClass c(8);

  a.printData();
  b.printData();
  c.printData();

  /* I want to explicitly destroy object b. */
  b.~myClass();
  b.printData();

  /* all the destructors get called when the objects go out of scope */

  return 0;
}

我的推理是这样的:我认为析构函数导致对象被销毁,所以它不再存在于内存中。在我显式调用析构函数之后,我应该不再能够再次使用该对象,因为它已被销毁。但是,我可以调用对象的函数并打印内部数据成员的值。手动调用析构函数是否无法销毁对象?这里发生了什么?输出:

default constructor called with 1
default constructor called with 1
constructor called with 8
object's data is 1
object's data is 1
object's data is 8
object 1 destroyed!
object's data is 1
object 8 destroyed!
object 1 destroyed!
object 1 destroyed!

调用析构函数会破坏对象,还是调用析构函数是破坏对象的结果?

标签: c++oopdestructor

解决方案


在我显式调用析构函数后,我应该不再能够再次使用该对象,因为它已被销毁

这是正确的。只是它是 C++,而不是像“当你做坏事时你会被警告”那样的“你不再能够”,它更像是“你可能会在未来任何随机点被击中脚,如果你做坏事”(又名“未定义的行为”)。

在您的特定示例中,您销毁了该对象,并且它在逻辑上不再存在。内存可能仍然被分配甚至包含一些旧数据。然而,试图访问它是未定义的行为。它可能对您的编译器、编译器标志、源代码、操作系统和月相的特定组合“起作用”,以后可能会以不同的方式工作,从技术上讲,它甚至可能会擦除您的硬盘驱动器

此外,当您在局部变量中声明对象时,它会在第二次超出范围时自动销毁。这也是未定义的行为,但你的程序的行为已经完全未定义并不重要。

您可以尝试使用 Valgrind、AddressSanitizer 或 UndefinedBehaviorSanitizer 等动态分析来捕获此类内容,但它们不提供任何保证。


推荐阅读