Bootstrap

C++类的默认成员函数 —— 拷贝构造函数

一、概念

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

二、特征

拷贝构造函数也是特殊的成员函数,其特征如下:

1. 拷贝构造函数是构造函数的一个重载形式。

2. 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

下面用代码解释一下:

class Data
{
public:
	Data(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	// Data(Data d) // 不加 & 的话 会出现循环拷贝
	// Data(Data& d) // 不加 const 的话,如果写成 d._year = _year 那么原本的值就会被随机值覆盖!所以用引用(&)就要加 const
	Data(const Data& d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};

void fun()
{
	Data d1(2022, 11, 1);
	Data d2(d1);
}

int main()
{
	fun();

	return 0;
}

下面是引发无穷递归调用的示例:

3. 若未显式定义,编译器会生成默认的拷贝构造函数,默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
注意:在编译器生成得到默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。 

下面用上面的代码屏蔽掉显示写的拷贝构造函数,在进行调试发现执行 Date d2(d1) 这句的时候,用已经存在的 d1 拷贝构造d2,此处会调用Date类的拷贝构造函数。

注意:类中如果没有涉及资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构 造函数是一定要写的,否则就是浅拷贝。

4. 拷贝构造函数典型调用场景:

①使用已存在对象创建新对象 ②函数参数类型为类类型对象 ③函数返回值类型为类类型对象

;