c++ 拷贝构造函数调用时机

本文通过具体的C++代码示例,详细解析了构造函数、拷贝构造函数及析构函数的工作原理。展示了不同情况下这些函数如何被调用,包括对象创建、复制以及销毁的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class A
{

public :A(int a)
		{
			b=a;
			c++;
			cout<<"construct A()"<<b<<"c"<<c<<endl;

		}
		A()
		{
			c++;
			cout<<"non argument method"<<b<<"c"<<c<<endl;
			

		}
		A(const A&a)
		{
			this->b=a.b;
			c++;
			cout<<"copy construct method"<<b<<"c"<<c<<endl;
		}
		~A()
		{
			c--;
			cout<<"destroy method"<<b<<"c"<<c<<endl;
			
		}
		int b;
		static int c;

};
int A::c=0;

class B
{
private: A a;
public:
	B(A a)
	{
		cout<<"here"<<endl;
		this->a=a;
		cout<<"here1"<<endl;
	}

};
A g();
int main()
{
	A a=g();
	cout<<"asd"<<endl;
	system("pause");
}
A g()
{
	A a=A(2);
	
	cout<<"here"<<endl;
	A c=a;
	cout<<"here1"<<endl;
	return NULL;
	//B b=B(a);
	//return a;

}


结果
construct A()2c1
here
copy construct method2c2
here1
construct A()0c3
destroy method2c2
destroy method2c1
asd
请按任意键继续. . .


1程序首先进入到函数g里面,先调用A的有参构造;

2 A c=a; 这一段调用A的拷贝构造函数,没有异议。 如果将程序改为   A c;  c=a;  程序将不会调用拷贝构造函数,而是调用系统默认的=操作符。

3 函数有返回值,并且返回值为值对象,所以调用默认


将程序的返回值改为 return a;

结果

construct A()2c1
here
copy construct method2c2
here1
copy construct method2c3
destroy method2c2
destroy method2c1
asd
请按任意键继续. . .

函数返回时程序调用A的拷贝构造函数(其中这个拷贝函数的参数为a)产生一个临时对象,该临时对象有个指针指向这个对象,该指针存储在寄存器中,当函数的堆栈销毁了,但是里面的值并没有擦除,所以依然可以借助这个寄存器的指针得到函数返回的这个临时对象的值。函数结束时先要销毁c对象(因为为自动变量存储在堆栈中先进后出原则),然后销毁a,最后函数执行完,再去销毁函数返回时调用拷贝构造函数产生的临时对象。如果你返回的Null则调用的会是普通的单个参数为int 型1的构造函数,如果没有程序则会报错。(如果你没有一个并且只有一个参数为int 的构造函数,系统尝试调用默认的拷贝构造函数,调用过程中会出现类型转换错误,将值1(null)转为const & xxx)。

如果函数返回的对象在调用的地方有存储(即上例中在main函数中 A a=g())则所谓的函数返回时创建的临时对象其实不是临时对象而是一个在main结束才释放的对象。


如果一个对象先声明(一般的声明和定义在同一语句中),在做赋值的话那么它将不会调用拷贝构造函数。即在对象的初始化中才会调用拷贝构造函数。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值