C++拷贝构造函数

概念

拷贝构造函数只有一个参数,且该形参是对本类类型对象的引用(一般用const修饰)。该函数是用已经存在的对象创建新的对象,该函数由编译器自动调用

特征

拷贝构造函数是构造函数的重载,是一个特殊的构造函数;拷贝构造函数的参数只有一个且必须是类类型对象的引用,如果使用传值的方式进行调用,编译器会直接报错,这会引发无穷递归调用;如果未显示定义,编译器会生成默认的拷贝构造函数,但生成的拷贝构造函数是浅拷贝或者叫值拷贝(如果类中没有涉及到资源申请时,拷贝构造函数可以不用写)。

复制代码
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//Date(const Date d)
	//{
	//	_year = d._year;
	//	_month = d._month;
	//	_day = d._day;
	//}
	Date(const Date& d)//与构造函数构成重载
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void Print()
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d(2025, 7, 31);
	Date d1 = d;
	Date d2(d);
	d1.Print();
	d2.Print();

	return 0;
}

当拷贝构造采用传值拷贝时,报错如图:

当用默认的拷贝构造函数拷贝栈类时,代码:

复制代码
class Stack
{
public:
	Stack(int capacity = 4)
	{
		_a = (int*)malloc(sizeof(int) * capacity);
		_size = 0;
		_capacity = 0;
	}
	//Stack(const Stack& st)//显示定义拷贝构造函数
	//{
	//	_a = (int*)malloc(sizeof(int) * st._capacity);
	//	_size = st._size;
	//	_capacity = st._capacity;
	//	memcpy(_a, st._a, sizeof(int) * _capacity);
	//}
	~Stack()
	{
		free(_a);
		_size = _capacity = 0;
	}
private:
	int* _a;
	int _size;
	int _capacity;
};

int main()
{
	Stack st;
	Stack st1 = st;
	return 0;
}

当未显示定义构造函数时,通过调试可以发现拷贝构造仅发生了值拷贝,如图:

这样会导致st和st1的_a指向同一块空间,这会导致调用析构函数时会对用一块空间重复释放,编译器报错。因此为了避免这一结果,必须要显示定义拷贝构造函数。

相关推荐
liu****13 分钟前
4.基础开发工具(一)
linux·开发语言·1024程序员节
文火冰糖的硅基工坊13 分钟前
[人工智能-大模型-72]:模型层技术 - 模型训练六大步:①数据预处理 - 基本功能与对应的基本组成函数
开发语言·人工智能·python
不是老弟14 分钟前
rwqsd
数据结构·c++·算法
小龙报18 分钟前
《C语言疑难点 --- 字符函数和字符串函数专题(上)》
c语言·开发语言·c++·算法·学习方法·业界资讯·visual studio
凭君语未可23 分钟前
深度解析Java的多态特性
java·开发语言
csbysj202034 分钟前
DTD 元素:XML 与 SGML 文档结构解析指南
开发语言
傻童:CPU1 小时前
C语言练习题
c语言·开发语言
极地星光1 小时前
协程:实战与系统集成(高级篇)
开发语言
咔咔咔的1 小时前
3461. 判断操作后字符串中的数字是否相等 I
c++
0和1的舞者1 小时前
《Git:从入门到精通(八)——企业级git开发相关内容》
大数据·开发语言·git·搜索引擎·全文检索·软件工程·初学者