C++ c++;函数之后立即调用析构函数

C++ c++;函数之后立即调用析构函数,c++,c++11,C++,C++11,在第一个main中,我们将调用copy构造函数来初始化两个对象c和d。然后我们将调用类中的第一个=运算符,然后对这两个对象调用两次析构函数,输出为I4I5c5d5d5 对于第二个main,我们调用默认构造函数,然后调用5的构造函数副本,然后调用类中的第二个运算符,在第二个运算符的末尾直接调用析构函数 我不明白为什么在第一个操作符中=在使用操作符后没有调用析构函数,而在第二个操作符中=在使用第二个操作符后立即调用析构函数 #include <iostream> using names

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

对于第二个main,我们调用默认构造函数,然后调用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;
  } */
#包括
使用名称空间std;
C类{
int i;
公众:

C():i(0){cout在
C=5行中;
没有任何赋值运算符获取可用的
int
,因此将创建一个临时
C(5)
,然后在赋值中使用


然后在语句末尾销毁该临时变量。

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

该临时文件将在语句末尾销毁。

第一版

最后的析构函数调用与
c=d;
无关

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

I4I5c5
第一个
I4
I5
分别是由语句
=4
=5
构造的对象,它们是由接受
int
的构造函数创建的无名临时对象

但是等等,如果我们将
c
d
分配给临时变量,为什么不调用我们的
c&operator=(c&&u-c)

这是因为复制省略。编译器可以完全消除此处的移动,即使它会产生副作用,并且它只是在适当的位置构造对象。代码相当于:

C a {4};
C b {5};
那么,最后一个,
c5
就是因为
c=d;


第二版

对于第二个版本,这种省略是不允许的,因为我们不立即构造对象。
cc=5;
vs
cc;C=5;
。因此为
5
创建的临时对象调用move assignment操作符,该操作符返回后立即销毁。

第一个版本

最后的析构函数调用与
c=d;
无关

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

I4I5c5
第一个
I4
I5
分别是由语句
=4
=5
构造的对象,它们是由接受
int
的构造函数创建的无名临时对象

但是等等,如果我们将
c
d
分配给临时变量,为什么不调用我们的
c&operator=(c&&u-c)

这是因为复制省略。编译器可以完全消除此处的移动,即使它会产生副作用,并且它只是在适当的位置构造对象。代码相当于:

C a {4};
C b {5};
那么,最后一个,
c5
就是因为
c=d;


第二版


对于第二个版本,这种省略是不允许的,因为我们不立即构造对象。
cc=5;
vs
cc;C=5;
。因此为
5
创建的临时对象调用move assignment操作符,该操作符返回后会立即销毁。

您说的是
first main
and
second main
,这两行代码是什么意思?main中的第一行和第二行代码,还是main的两个不同版本?如果输出是
I4I5c5d5d5
,则没有调用复制构造函数。您说
first main
second main
,这两行代码是什么意思?co的第一行和第二行代码de in main或main的两个不同版本?如果输出为
I4I5c5d5d5
,则不会调用复制构造函数。