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

C++ 析构函数和复制构造函数调用..(为什么在这些时候调用它),c++,gcc,class,destructor,copy-constructor,C++,Gcc,Class,Destructor,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 <&

我有以下代码

#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;
}
我对此有一些问题,首先,为什么
objectv4=v1
调用复制构造函数,在打印
(b)
后生成
复制构造函数(1)

同样在打印了
(c)
之后,复制构造函数又被调用了两次,我不确定这个函数是如何产生这个结果的
objectfunc(objectvar){returnvar;}

在这之后,
Destruct(1)
被调用两次,然后打印
(d)


很抱歉回答了这么长的问题,我把上面的问题弄糊涂了。

至于第一个问题,
objectv4=v1
对象v4(v1)的语法糖,它显然调用了复制构造函数

第二个比较复杂。当按值向函数传递变量时,必须复制它们-因此需要调用复制构造函数。对象的副本也必须放在堆栈上调用方可以访问它的位置,因为传递给函数的副本在函数返回时不再存在。制作这两个副本后,参数将在从堆栈弹出时被销毁,返回值将被销毁,因为它的值未被使用。它们具有相同的ID,因为它们是
v1
的副本

首先,我有一些问题 为什么对象v4=v1;呼叫副本 建造商和生产商 打印后复制构造(1) 第(b)款

尽管有
=
符号,您仍在这里调用复制构造函数。请记住,您没有默认构造函数。您正在构造一个新的
对象
,并使用
v1
值对其进行初始化。你要做什么

cout << "( b )" << endl;
Object v4(0);
v4 = v1;
…我想这是你期待的

同样在打印(c)之后 再次调用复制构造函数 两次?我不确定这是怎么回事 函数用于生成该对象 func(对象变量){return var;}

这里,您通过值(而不是引用[&])传递
var
,这意味着创建了对象的副本(一次对副本构造函数的调用)。然后返回另一个对象 (同样,不是引用),因此必须进行另一个副本(对副本构造函数的第二次调用)

在破坏(1)之后 在打印(d)之前调用两次

您刚才用复制构造函数创建的那些对象?它们只是超出了范围,它们的析构函数被调用

当您
delete
v5
时,将调用其析构函数

然后到达
main
函数的末尾,在堆栈上创建的三个
对象
实例(
v1
v2
v4
)到达其生命周期的末尾,并在堆栈展开时销毁

您可能已经注意到,析构函数调用的数量与构造函数调用的数量完全相同

Object v1(1);
// Construct(1)
自动堆栈变量的常规构造函数调用(在函数末尾销毁)

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

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

Object v4 = v1;
// Copy-construct(1)
调用堆对象的构造函数(使用
delete
显式销毁)


非常感谢。还有一个问题,
Destruct(1)
的最后3个输出是由于
对象v1(1);,v2=v1,对象v4=v1正确吗?而
析构函数(5)
就在它被手动删除之前出现?您能解释一下最后4个析构函数调用吗?。
Object v1(1);
// Construct(1)
cout << "( a )" << endl;
// ( a )

Object v2(2);
// Construct(2)
v2 = v1;
// 2 = 1
cout << "( b )" << endl;
// ( b )

Object v4 = v1;
// Copy-construct(1)
Object *pv5;
pv5 = &v1;
pv5 = new Object(5);
// Construct(5)
cout << "( c )" << endl;
// ( c )

func(v1);
// Copy-construct(1) <br />
// Copy-construct(1) <br />
// Destruct(1) <br />
// Destruct(1) <br />
cout << "( d )" << endl;
// ( d )

delete pv5;
// Destruct(5)
} // end of main
// Destruct(1) <br />
// Destruct(1) <br />
// Destruct(1) <br />