C++ - 错误的析构函数被调用

4

我对析构函数有一些理解上的问题。

在以下示例中:

#include <iostream>

using namespace std;

class X{
public:
    int id;
    X(int id){
        this->id = id;
    }
    ~X(){
        cout << "destroying " << id;
    }

};



int main(){


    X a(1);
    a = X(2);


    while(true);
    return 0;

}

我得到了以下输出:销毁2 这对我来说完全出乎意料,因为我认为当对象停止存在时,析构函数总是会被调用。
但在这个例子中,停止存在的是对象1,并被对象2替代。但是,与其调用对象1的析构函数,却调用了对象2的析构函数。
有人能解释一下吗?

a只有在main函数返回后才停止存在,在此期间它从未停止存在,您只能使用op=对其进行赋值。 - PlasmaHH
2个回答

5
在您的情况下,只有一个对象被销毁 - 即右侧赋值语句中的临时X(2)。原始的X(1)没有被销毁,因为它被赋值覆盖了。当它需要被销毁时,它也会打印destroying 2
然而,被修改的X(2)(最初是X(1))由于无限循环而保持活动状态,因此也不会被销毁。删除无限循环可以解决这个问题(演示)。

这是一个非常好的答案,但在阅读@PlasmaHH的评论提到赋值运算符后,我才能理解它。我认为你也应该在你的答案中提到这一点;因为起初,我以为(1)应该被销毁,然后它在内存中的空间应该被新的(2)副本填充。但实际上发生的是,(1)只是被修改以匹配(2)。 - Van Coding
@VanCoding 我说“assignment”两次,假设你知道它是一个运算符 :) - Sergey Kalinichenko
我知道,但是一个赋值操作可能会被解释成不同的意思,就像你看到的那样 :D 我以为是将内存分配给 (1),而不是调用一个将 (1) 转换为 (2) 的函数。 - Van Coding

2

a = X(2); => 表达式调用赋值运算符,并使用临时对象的id即2来初始化a对象的数据成员a.id。

a = X(2); => 表达式调用编译器提供的默认赋值运算符并进行浅拷贝。

X(2)表达式创建一个临时对象,临时对象的id被初始化为2。

第一次析构函数被调用是在临时对象被另一个a对象调用时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接