析构函数和复制构造函数调用..(为什么在这些时候被调用)

sil*_*ent 2 c++ gcc destructor class copy-constructor

我有以下代码

#include <iostream>
using namespace std;

class Object {

public:
   Object(int id){
     cout << "Construct(" << id << ")" << endl; 
     m_id = id;       
   }

   Object(const Object& obj){
      cout << "Copy-construct(" << obj.m_id << ")" << endl;  
      m_id = obj.m_id;
   }

   Object& operator=(const Object& obj){
      cout << m_id << " = " << obj.m_id << endl; 
      m_id = obj.m_id;
      return *this; 
   }

   ~Object(){
       cout << "Destruct(" << m_id << ")" << endl; 
   }
private:
   int m_id;

};

Object func(Object var) { return var; }

int main(){
   Object v1(1);
   cout << "( a )" << endl;
   Object v2(2);
   v2 = v1;
   cout << "( b )" << endl;
   Object v4 = v1;
   Object *pv5;
   pv5 = &v1;
   pv5 = new Object(5);
   cout << "( c )" << endl;
   func(v1);
   cout << "( d )" << endl;
   delete pv5;
}
Run Code Online (Sandbox Code Playgroud)

哪个输出

Construct(1)
( a )
Construct(2)
2 = 1
( b )
Copy-construct(1)
Construct(5)
( c )
Copy-construct(1)
Copy-construct(1)
Destruct(1)
Destruct(1)
( d )
Destruct(5)
Destruct(1)
Destruct(1)
Destruct(1)
Run Code Online (Sandbox Code Playgroud)

我有一些问题,为此,首先为什么Object v4 = v1;调用拷贝构造函数和农产品Copy-construct(1)印刷后( b )

同样在( c )复制构造函数的打印再次被调用两次之后?,我不确定这个函数是如何工作的 Object func(Object var) { return var; }

然后 Destruct(1)( d )打印之前被调用两次。

抱歉问了这么长的问题,我对上面的内容感到困惑。

Fir*_*aad 5

Object v1(1);
// Construct(1)
Run Code Online (Sandbox Code Playgroud)

常规构造函数调用自动堆栈变量(在函数结束时销毁)。

cout << "( a )" << endl;
// ( a )

Object v2(2);
// Construct(2)
Run Code Online (Sandbox Code Playgroud)

另一个构造函数调用。

v2 = v1;
// 2 = 1
Run Code Online (Sandbox Code Playgroud)

调用赋值运算符是因为已经创建了 v2(我们为它调用了构造函数),现在我们将一个现有对象分配给另一个对象。

cout << "( b )" << endl;
// ( b )

Object v4 = v1;
// Copy-construct(1)
Run Code Online (Sandbox Code Playgroud)

此处调用复制构造函数是因为Object v4 仍未创建,因此我们将其创建为v1 的副本。此处的赋值与您所做的相同Object v4(v1)

Object *pv5;
pv5 = &v1;
pv5 = new Object(5);
// Construct(5)
Run Code Online (Sandbox Code Playgroud)

调用堆对象的构造函数(使用 显式销毁delete)。

cout << "( c )" << endl;
// ( c )

func(v1);
// Copy-construct(1) <br />
// Copy-construct(1) <br />
// Destruct(1) <br />
// Destruct(1) <br />
Run Code Online (Sandbox Code Playgroud)

首先调用复制构造函数将 v1 复制到参数 var。再次调用它以创建 var 的副本作为调用者的返回值。var 在退出函数时从堆栈中弹出时被销毁。返回值在表达式 func(v1) 之后被销毁。

cout << "( d )" << endl;
// ( d )

delete pv5;
// Destruct(5)
Run Code Online (Sandbox Code Playgroud)

pv5 指向的对象被手动销毁。

} // end of main
// Destruct(1) <br />
// Destruct(1) <br />
// Destruct(1) <br />
Run Code Online (Sandbox Code Playgroud)

自动变量 v1、v2、v4(都从赋值或复制构造中复制了 v1 的 id)从堆栈中弹出,并为每个变量调用析构函数。