C++ 函数紧随其后调用析构函数

c++ function call the destructor immediately after

本文关键字:调用 析构函数 函数 C++      更新时间:2023-10-16

在第一个主文件中,我们将调用复制构造函数来初始化两个对象 c 和 d。然后我们将调用我类中的第一个 = 运算符,然后为两个对象调用析构函数两次,输出为 I4I5c5d5d5

对于第二个主运算符,我们调用默认构造函数,然后调用5 的构造函数副本,然后我们调用我的类中的第二个运算符,在第二个运算符的末尾直接调用析构函数。

我不明白为什么在第一个运算符=中使用运算符后不调用析构函数,为什么在第二个运算符=中使用第二个运算符后立即调用析构函数。

#include <iostream>
using namespace std;
class C {
int i;
public:

C() : i(0)                  { cout << "D" << i; }
C(int _i) : i(_i)           { cout << "I" << i; }
C(const C& _c) : i(_c.i)    { cout << "C" << i;  }
C& operator= ( const C& _c) { i = _c.i; cout << "c" << i; return *this; }
C(C&& _c) : i(_c.i)         { cout << "M" << i; _c.i = 0; }
C& operator= (C&& _c)       { i = _c.i; cout << "m" << i; _c.i = 0;
return *this; }
~C()                        { cout << "d" << i;  }
};

int main() {
C c = 4;
C d = 5;
c = d;
}
/* int main() {
C c;
c = 5;
} */

在行c = 5;中,没有任何赋值运算符采用可用的int,因此将创建一个临时C(5),然后在赋值中使用。

然后,此临时将在语句末尾销毁。

第一个版本

最后一个析构函数调用与c = d;无关。

之所以调用它们,是因为cd超出了范围,因此它们被销毁了,所以让我们从结果中删除它们,这给了我们:

I4I5c5

I4I5分别是由语句= 4= 5构造的对象,它们是由接受int的构造函数创建的无名称临时。

但是等等,如果我们把cd分配给临时工,为什么我们的C& operator= (C&& _c)不被召唤呢?

那是因为复制省略。允许编译器完全消除此处的移动,即使它会产生副作用,并且它只是就地构造对象。该代码等效于:

C a {4};
C b {5};

然后,最后一个,c5只是因为c = d;.


第二版

对于第二个版本,不允许使用这种省略,因为我们不会立即构造对象。C c = 5;vsC c; c = 5;.因此,为5创建的临时运算符调用移动赋值运算符,然后在运算符返回后立即销毁。