C++ 拷贝构造函数应用场景

本文通过四个场景详细阐述了C++中构造函数、拷贝构造函数和析构函数的使用。场景一展示了拷贝构造函数的典型应用,场景二说明了赋值运算符如何替代拷贝构造,场景三探讨了函数参数传递中对象的生命周期,场景四和五解释了返回对象时临时对象的处理,以及如何避免临时对象的立即销毁。每个场景都通过输出调用的构造和析构函数来清晰地呈现对象的生命周期。

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

第一个场景
#include <iostream>

using namespace std;

class Test{
	
	public:
		//默认构造函数。 就是一个无参数的构造函数,
		//如果不显示提供构造函数,系统就是调用默认的构造函数
		/*
		Test() {} 默认的构造函数,已经手动提供,默认就被隐藏
		*/
	
		//如果我们提供了一个显示的构造函数,那么默认的构造函数就被隐藏掉了。
		//构造函数一旦手动提供, 默认将不复存在。
		Test(int x, int y){
			cout << "-----------------------" << endl;
			m_x = x;
			m_y = y;
			cout << "调用了有参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//无参数的构造函数
		Test() {
			
			cout << "-----------------------" << endl;
			m_x = 0;
			m_y = 0;
			cout << "调用了无参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
	
		//拷贝构造函数 ,想通过另一个Test对象 another 将本对象进行拷贝
		Test(const Test& another){
			cout << "-----------------------" << endl;
			m_x = another.m_x;
			m_y = another.m_y;
			cout << "调用了拷贝构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//等号操作符
		void operator = (const Test& t){
			
			cout << "-----------------------" << endl;
			cout << "调用了=号操作符" << endl;
			m_x = t.m_x;
			m_y = t.m_y;
			cout << "-----------------------" << endl;
		}
	
		void printT(){
			cout << "-----------------------" << endl;
			cout << "x : " << m_x << ", y : " << m_y << endl;
			cout << "-----------------------" << endl;
		}
	
		//提供一个析构函数
		~Test(){
			cout << "-----------------------" << endl;
			cout << "~Test()析构函数被执行了" << endl;
			cout << "(" << m_x << ", " << m_y << ")" << "被析构了" << endl;
			cout << "-----------------------" << endl;
		}
	
	private:
		int m_x;
		int m_y;
};


//拷贝构造函数的第一个场景
void test1(){
	Test t1(1, 2);  // 调用了有参数的构造函数 
	Test t2(t1);   // 调用了拷贝构造函数
	//通过t1 给t2 进行赋值

	t2.printT(); // 打印 x, y的值
	//  t2.printT(); 结束后,
	// t2 会先调用 ~Test()析构函数
	// t1 最后调用  ~Test()析构函数
	
}

int main(void){
	 test1();
}
第二个场景
#include <iostream>

using namespace std;

class Test{
	
	public:
		//默认构造函数。 就是一个无参数的构造函数,
		//如果不显示提供构造函数,系统就是调用默认的构造函数
		/*
		Test() {} 默认的构造函数,已经手动提供,默认就被隐藏
		*/
	
		//如果我们提供了一个显示的构造函数,那么默认的构造函数就被隐藏掉了。
		//构造函数一旦手动提供, 默认将不复存在。
		Test(int x, int y){
			cout << "-----------------------" << endl;
			m_x = x;
			m_y = y;
			cout << "调用了有参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//无参数的构造函数
		Test() {
			
			cout << "-----------------------" << endl;
			m_x = 0;
			m_y = 0;
			cout << "调用了无参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
	
		//拷贝构造函数 ,想通过另一个Test对象 another 将本对象进行拷贝
		Test(const Test& another){
			cout << "-----------------------" << endl;
			m_x = another.m_x;
			m_y = another.m_y;
			cout << "调用了拷贝构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//等号操作符
		void operator = (const Test& t){
			
			cout << "-----------------------" << endl;
			cout << "调用了=号操作符" << endl;
			m_x = t.m_x;
			m_y = t.m_y;
			cout << "-----------------------" << endl;
		}
	
		void printT(){
			cout << "-----------------------" << endl;
			cout << "x : " << m_x << ", y : " << m_y << endl;
			cout << "-----------------------" << endl;
		}
	
		//提供一个析构函数
		~Test(){
			cout << "-----------------------" << endl;
			cout << "~Test()析构函数被执行了" << endl;
			cout << "(" << m_x << ", " << m_y << ")" << "被析构了" << endl;
			cout << "-----------------------" << endl;
		}
	
	private:
		int m_x;
		int m_y;
};

//拷贝构造函数的第二场景
void test2()
{
	Test t1(1, 2);  // 调用了有参数的构造函数 
	Test t2;   // 调用了无参数的构造函数
	t2 = t1; //调用的不是拷贝构造函数,调用的是 =号操作符,也能够完成将t1的值给t2 但不是调用t2的拷贝构造函数。
	// 结束 
	// t2 会先调用 ~Test()析构函数
	// t1 最后调用  ~Test()析构函数
}

int main(void){
	 test2();

}
第三个场景
#include <iostream>

using namespace std;

class Test{
	
	public:
		//默认构造函数。 就是一个无参数的构造函数,
		//如果不显示提供构造函数,系统就是调用默认的构造函数
		/*
		Test() {} 默认的构造函数,已经手动提供,默认就被隐藏
		*/
	
		//如果我们提供了一个显示的构造函数,那么默认的构造函数就被隐藏掉了。
		//构造函数一旦手动提供, 默认将不复存在。
		Test(int x, int y){
			cout << "-----------------------" << endl;
			m_x = x;
			m_y = y;
			cout << "调用了有参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//无参数的构造函数
		Test() {
			
			cout << "-----------------------" << endl;
			m_x = 0;
			m_y = 0;
			cout << "调用了无参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
	
		//拷贝构造函数 ,想通过另一个Test对象 another 将本对象进行拷贝
		Test(const Test& another){
			cout << "-----------------------" << endl;
			m_x = another.m_x;
			m_y = another.m_y;
			cout << "调用了拷贝构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//等号操作符
		void operator = (const Test& t){
			
			cout << "-----------------------" << endl;
			cout << "调用了=号操作符" << endl;
			m_x = t.m_x;
			m_y = t.m_y;
			cout << "-----------------------" << endl;
		}
	
		void printT(){
			cout << "-----------------------" << endl;
			cout << "x : " << m_x << ", y : " << m_y << endl;
			cout << "-----------------------" << endl;
		}
	
		//提供一个析构函数
		~Test(){
			cout << "-----------------------" << endl;
			cout << "~Test()析构函数被执行了" << endl;
			cout << "(" << m_x << ", " << m_y << ")" << "被析构了" << endl;
			cout << "-----------------------" << endl;
		}
	
	private:
		int m_x;
		int m_y;
};

void func(Test t){ //Test t = test1::t1; //会调用局部变量t的拷贝构造函数
	/*
		局部创建的 Test t 在 void func(Test t) 代码块结束后,会被析构
	*/
	cout << "func begin..." << endl;
	t.printT();  // 打印 x , y 的值 
	cout << "func end..." << endl;

}

//场景三
void test3(){
	cout << "test3 begin ..." << endl;
	Test t1(10, 20); //创建了一个t1的对象。调用t1的有参数的构造函数   
	func(t1);

	cout << "test3 end..." << endl;
	
	// 结束后,调用  t1的析构函数 
}

int main(void){
	 test3();

}
第四个场景
#include <iostream>

using namespace std;

class Test{
	
	public:
		//默认构造函数。 就是一个无参数的构造函数,
		//如果不显示提供构造函数,系统就是调用默认的构造函数
		/*
		Test() {} 默认的构造函数,已经手动提供,默认就被隐藏
		*/
	
		//如果我们提供了一个显示的构造函数,那么默认的构造函数就被隐藏掉了。
		//构造函数一旦手动提供, 默认将不复存在。
		Test(int x, int y){
			cout << "-----------------------" << endl;
			m_x = x;
			m_y = y;
			cout << "调用了有参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//无参数的构造函数
		Test() {
			
			cout << "-----------------------" << endl;
			m_x = 0;
			m_y = 0;
			cout << "调用了无参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
	
		//拷贝构造函数 ,想通过另一个Test对象 another 将本对象进行拷贝
		Test(const Test& another){
			cout << "-----------------------" << endl;
			m_x = another.m_x;
			m_y = another.m_y;
			cout << "调用了拷贝构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//等号操作符
		void operator = (const Test& t){
			
			cout << "-----------------------" << endl;
			cout << "调用了=号操作符" << endl;
			m_x = t.m_x;
			m_y = t.m_y;
			cout << "-----------------------" << endl;
		}
	
		void printT(){
			cout << "-----------------------" << endl;
			cout << "x : " << m_x << ", y : " << m_y << endl;
			cout << "-----------------------" << endl;
		}
	
		//提供一个析构函数
		~Test(){
			cout << "-----------------------" << endl;
			cout << "~Test()析构函数被执行了" << endl;
			cout << "(" << m_x << ", " << m_y << ")" << "被析构了" << endl;
			cout << "-----------------------" << endl;
		}
	
	private:
		int m_x;
		int m_y;
};



// 第四场景
Test func2()
{
	cout << "func2 begin..." << endl;
	Test temp(10, 20); //调用temp的带参数构造函数  
	cout << "func2 end.." << endl;
	return temp; // 有一个临时的匿名对象 = temp ,把temp的数据给到了临时的匿名对象,  ,会调用这个临时匿名
						//对象的拷贝构造函数, 将temp穿进去。
}

void test4(){
	cout << "test4 begin " << endl;
	func2();

	//匿名对象在此被析构了, 如果一个临时的匿名对象,没有任何变量去接收它,编译器认为这个临时匿名对象没有用处。
	//编译器会立刻销毁这个临时的匿名对象
	cout << "test4 end" << endl;
}

int main(void){
	test4();

}
第五个场景
#include <iostream>

using namespace std;

class Test{
	
	public:
		//默认构造函数。 就是一个无参数的构造函数,
		//如果不显示提供构造函数,系统就是调用默认的构造函数
		/*
		Test() {} 默认的构造函数,已经手动提供,默认就被隐藏
		*/
	
		//如果我们提供了一个显示的构造函数,那么默认的构造函数就被隐藏掉了。
		//构造函数一旦手动提供, 默认将不复存在。
		Test(int x, int y){
			cout << "-----------------------" << endl;
			m_x = x;
			m_y = y;
			cout << "调用了有参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//无参数的构造函数
		Test() {
			
			cout << "-----------------------" << endl;
			m_x = 0;
			m_y = 0;
			cout << "调用了无参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
	
		//拷贝构造函数 ,想通过另一个Test对象 another 将本对象进行拷贝
		Test(const Test& another){
			cout << "-----------------------" << endl;
			m_x = another.m_x;
			m_y = another.m_y;
			cout << "调用了拷贝构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//等号操作符
		void operator = (const Test& t){
			
			cout << "-----------------------" << endl;
			cout << "调用了=号操作符" << endl;
			m_x = t.m_x;
			m_y = t.m_y;
			cout << "-----------------------" << endl;
		}
	
		void printT(){
			cout << "-----------------------" << endl;
			cout << "x : " << m_x << ", y : " << m_y << endl;
			cout << "-----------------------" << endl;
		}
	
		//提供一个析构函数
		~Test(){
			cout << "-----------------------" << endl;
			cout << "~Test()析构函数被执行了" << endl;
			cout << "(" << m_x << ", " << m_y << ")" << "被析构了" << endl;
			cout << "-----------------------" << endl;
		}
	
	private:
		int m_x;
		int m_y;
};


Test func2(){
	cout << "func2 begin..." << endl;
	Test temp(10, 20); //调用temp的带参数构造函数  
	cout << "func2 end.." << endl;
	return temp; // 有一个临时的匿名对象 = temp ,把temp的数据给到了临时的匿名对象,  ,会调用这个临时匿名
						//对象的拷贝构造函数, 将temp穿进去。
}



// 第五场景
void test5(){
	cout << "test5 begin ..." << endl;
	Test t1 = func2();//如果有一个变量去接收这个临时的匿名对象, 编译器认为这个匿名对象转正了,就不会立刻给他销毁。
							//t1 = 匿名的临时对象 为什么不会发生拷贝构造
							//	此时的t1 去接收这个匿名的临时对象不是 重新创建一个t1 而是给这个匿名对象起个名字就叫t1
							//一旦这个匿名对象有了自己的名字,编译器就不会立刻给这个匿名对象销毁了,
							//就当普通局部变量处理了

	cout << "test5 end..." << endl;

	//在此时析构的t1
}

int main(void){
	test5();
}
第六个场景
#include <iostream>

using namespace std;

class Test{
	
	public:
		//默认构造函数。 就是一个无参数的构造函数,
		//如果不显示提供构造函数,系统就是调用默认的构造函数
		/*
		Test() {} 默认的构造函数,已经手动提供,默认就被隐藏
		*/
	
		//如果我们提供了一个显示的构造函数,那么默认的构造函数就被隐藏掉了。
		//构造函数一旦手动提供, 默认将不复存在。
		Test(int x, int y){
			cout << "-----------------------" << endl;
			m_x = x;
			m_y = y;
			cout << "调用了有参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//无参数的构造函数
		Test() {
			
			cout << "-----------------------" << endl;
			m_x = 0;
			m_y = 0;
			cout << "调用了无参数的构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
	
		//拷贝构造函数 ,想通过另一个Test对象 another 将本对象进行拷贝
		Test(const Test& another){
			cout << "-----------------------" << endl;
			m_x = another.m_x;
			m_y = another.m_y;
			cout << "调用了拷贝构造函数" << endl;
			cout << "-----------------------" << endl;
		}
	
		//等号操作符
		void operator = (const Test& t){
			
			cout << "-----------------------" << endl;
			cout << "调用了=号操作符" << endl;
			m_x = t.m_x;
			m_y = t.m_y;
			cout << "-----------------------" << endl;
		}
	
		void printT(){
			cout << "-----------------------" << endl;
			cout << "x : " << m_x << ", y : " << m_y << endl;
			cout << "-----------------------" << endl;
		}
	
		//提供一个析构函数
		~Test(){
			cout << "-----------------------" << endl;
			cout << "~Test()析构函数被执行了" << endl;
			cout << "(" << m_x << ", " << m_y << ")" << "被析构了" << endl;
			cout << "-----------------------" << endl;
		}
	
	private:
		int m_x;
		int m_y;
};


Test func2(){
	cout << "func2 begin..." << endl;
	Test temp(10, 20); //调用temp的带参数构造函数  
	cout << "func2 end.." << endl;
	return temp; // 有一个临时的匿名对象 = temp ,把temp的数据给到了临时的匿名对象,  ,会调用这个临时匿名
						//对象的拷贝构造函数, 将temp穿进去。
}



// 第六场景
void test6(){
	cout << "test6 begin..." << endl;
	Test t1; //调用t1的无参数构造函数
	t1 = func2(); //调用的=号操作符 ,,t1 = 匿名对象。 调用了t1的=号操作符。
						//此时匿名没有被转正,匿名没有自己的名字, 匿名对象这个内存没有自己的别名, 编译器就会立刻销毁。
	cout << "test6 end..." << endl;
}

int main(void){
	test6();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值