C++ 中的析构函数调用

发布于 2024-12-11 10:55:33 字数 1351 浏览 2 评论 0原文

我研究过,每当对象超出范围或使用delete 运算符取消分配给它的内存时,就会调用Destructor

#include  <iostream>

using namespace std;

class point
{
   private:
      int x_coord;
      int y_coord;

   public:
      point()
      {
         x_coord = 0;
         y_coord = 0;
      }

      point(int x, int y)
      {
         x_coord = (x > 79 ? 79 : (x < 0 ? 0 : x));
         y_coord = (y > 79 ? 79 : (y < 0 ? 0 : y));
      }

      ~point()
      {
         cout << "Destructor invoked\n";
      }

      int getx(void)
      {
         return x_coord;
      }

      int gety(void)
      {
         return y_coord;
      }
};

int main()
{
   point p1;
   point p2(20, 80);

   point *p3 = new point;

   cout << "p1.x =  " << p1.getx() << ": p1.y = " << p1.gety()<< "\n";
   cout << "p2.x =  " << p2.getx() << ": p2.y = " << p2.gety()<< "\n";
   cout << "p3->x =  " << p3->getx() << ": p3->y = " << p3->gety()<< "\n";

   point * p4 = &p1;
   delete p4;
   delete p3;

   return 0;

}
  1. 使用delete p4 取消分配给p1 的内存。因此析构函数被调用
  2. delete p3 调用下一个析构函数。
  3. p2 超出范围并调用下一个析构函数。

我预计析构函数只会被调用 3 次。但我看到析构函数被调用了 4 次。这是什么原因呢?我对析构函数的理解是否有一些错误

I have studied that Destructor is invoked whenever the object goes out of scope or when the memory allocated to it is de-allocated using the delete operator.

#include  <iostream>

using namespace std;

class point
{
   private:
      int x_coord;
      int y_coord;

   public:
      point()
      {
         x_coord = 0;
         y_coord = 0;
      }

      point(int x, int y)
      {
         x_coord = (x > 79 ? 79 : (x < 0 ? 0 : x));
         y_coord = (y > 79 ? 79 : (y < 0 ? 0 : y));
      }

      ~point()
      {
         cout << "Destructor invoked\n";
      }

      int getx(void)
      {
         return x_coord;
      }

      int gety(void)
      {
         return y_coord;
      }
};

int main()
{
   point p1;
   point p2(20, 80);

   point *p3 = new point;

   cout << "p1.x =  " << p1.getx() << ": p1.y = " << p1.gety()<< "\n";
   cout << "p2.x =  " << p2.getx() << ": p2.y = " << p2.gety()<< "\n";
   cout << "p3->x =  " << p3->getx() << ": p3->y = " << p3->gety()<< "\n";

   point * p4 = &p1;
   delete p4;
   delete p3;

   return 0;

}
  1. The memory allocated to p1 is de-allocated using delete p4. So destructor is invoked
  2. delete p3 invokes the next destructor.
  3. p2 goes out of scope and the next destructor is invoked.

I expected destructor to be invoked only 3 times. But i see the destructor invoked 4 times. What is the reason for this? Is there some mistake with respect to my understanding of destructors

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

始终不够 2024-12-18 10:55:33

代码中有错误。您无法删除 p1p4 指向 p1),因为它不是使用 new 创建的。因此,程序正在调用未定义的行为。

在这种特殊情况下,p1 的析构函数被调用两次:第一次是 delete,第二次是 p1 超出范围。也可能是其他任何结果(另一个可能的结果是崩溃)。

There is mistake in the code. You can not delete p1 (p4 points to p1) as it was not created with new. Thus, the program is invoking undefined behavior.

What happens in this particular case is that p1's destructor gets invoked twice: first with delete, second time when p1 goes out of scope. It could be anything else as well (the other likely outcome is crash).

栩栩如生 2024-12-18 10:55:33

您将销毁 p1 两次,一次是当 p1 超出范围时,一次是当您调用 delete p4 时,它只是一个指向 p4 的指针。 code>p1,而不是单独的对象。顺便说一句,两次销毁一个对象是未定义的行为(就像删除堆栈对象一样(参见注释))。

You are destroying p1 twice, once when p1 goes out of scope, but also when you invoke delete p4, which is just a pointer to p1, not to a separate object. Destroying an object twice is undefined behaviour, btw (as is deleting a stack object (see comment)).

她比我温柔 2024-12-18 10:55:33

p1 已在堆栈上分配,因此即使您在 p4 上调用了 delete,delete 也会在现在未分配的 p1 上调用

请注意,释放内存并不(必然)将其清零。因此析构函数有可能被再次调用并打印消息。或者它可能会爆炸。这就是为什么确保在上次使用之前不释放内存至关重要。

p1 was allocated on the stack, so even though you called delete on p4, delete will be called on the now-unallocated p1.

Note that deallocating memory doesn't (necessarily) zero it out. So it is possible for the destructor to be called again and print the message. Or it might blow up. That is why it is critical to ensure that you don't deallocate memory before your last use.

忆沫 2024-12-18 10:55:33

如果您使用调试 CRT 进行编译,通过指针 p4 对 p1 的破坏是无效的,并且会引发运行时错误。

Your destruction of p1 through pointer p4 is invalid and will throw a runtime error if you are compiling with the debug CRT.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文