C++:拷贝构造函数&赋值运算符的重载函数

匿名 (未验证) 提交于 2019-12-02 23:00:14

拷贝构造函数

默认的拷贝构造函数


深拷贝&浅拷贝:


思考:
当对象中存在指针成员时,为什么需要自己实现拷贝构造函数?如果不,会出现怎样的问题?

看代码

 #include<iostream>  class CGoods { public: 	CGoods(const char* name, double price, int amount)//带有三个参数的构造函数 	{ 		std::cout << this << " :CGoods::CGoods(char*,float,int)" << std::endl; 		mname = new char[strlen(name) + 1](); 		strcpy(mname, name); 		mprice = price; 		mamount = amount; 	}  	CGoods()//不带参数的构造函数 	{ 		std::cout << this << " :CGoods::CGoods()" << std::endl; 		mname = new char[1](); 	} private: 	char*  mname; 	double mprice; 	int mamount; };  int main() { 	CGoods good1("car1", 10.1, 10); 	CGoods good2 = good1; 	return 0; }

程序运行结果:调一次构造函数,调两次析构函数。

分析:两个对象的指针成员所指内存相同,这会导致什么问题呢?

所以需要我们不得不自己写一个拷贝构造函数。

 CGoods(const CGoods& rhs) { 	mname = new char[strlen(rhs.mname) + 1](); 	strcpy(mname, rhs.mname); 	mprice = rhs.mprice; 	mamount = rhs.mamount; }  

注意:拷贝构造函数传参必须传引用。若正常传,则会不断地递归去生成新形参对象,最后导致栈溢出。也不能用*,若写成 CGoods(const CGoods* rhs),就会变成一个构造函数,CGoods*传的是已存在对象的地址。

赋值运算符的重载函数:

默认赋值运算符的重载函数:

 CGoods& operator=(const CGoods& rhs) { 	std::cout << this << " CGoods::operator=(const CGoods&)" << std::endl; 	if (this != &rhs)//判断是否给自己赋值 	{ 		delete[] mname;//防止内存泄漏 		mname = new char[strlen(rhs.mname) + 1]();  		strcpy(mname, rhs.mname); 		mprice = rhs.mprice; 		mamount = rhs.mamount; 	} 	return *this; }  

思考:为什么要避免自赋值呢?
1)自己给自己赋值完全是毫无意义,为了效率。

2)如果类的数据成员中含有指针,自赋值有时会导致灾难性的后果。对于指针间的赋值,先要将p所指向的空间delete掉,然后再为p重新分配空间,将被拷贝指针所指的内容拷贝到p所指的空间。如果是自赋值,那么p和被拷贝指针是同一指针,在赋值操作前对p的delete操作,将导致p所指的数据同时被销毁。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!