一:什么是拷贝构造函数?
顾名思义拷贝构造就是先拷贝一个已经存在的对象,然后构造另一个对象。
用来复制对象的,在使用这个对象的示例来初始化这个对象的一个新的示例。
二:为什么要用到拷贝构造函数?
通俗易懂地来说就是为了来定义初始化一个与已经存在的对象相同的对象,但是这里要注意:他们所获得的资源不同!
我们在C中用一个已经存在的变量去初始化另一个变量是:int a = b;那么应用于类中的对象时,由于对象所拥有的资源(类对象成员和对象的成员方法)是许多的,系统在默认情况下是不允许直接将一个对象直接初始化赋值给另一对象的,例如:CStudent student1 = student2;//student2 已经存在。所以呢我们必须调用拷贝构造函数。拷贝构造函数分为两种:
1.当自己没有实现拷贝构造函数时,编译器会自动生成浅拷贝的构造函数(值传递)
2.自己设置拷贝构造函数。
三:拷贝构造函数的特点
1.
什么是浅拷贝?只是简单地将一个对象内存的数据复制给另一个对象,这样做会导致一个问题,这两个对象如果有堆区的资源(外部资源)时,那么在这两个对象析构的时间,会对同一个heap区的空间,delete了两次,这样会导致程序崩溃。所以当这种情况出现时,我们最好自己实现拷贝构造函数(对外部资源的拷贝构造做一些处理),这也就是硬拷贝。
2.
拷贝构造函数,顾名思义他也是属于构造函数的一种,那么构造函数具有的特点他都有,比如无法使用对象来调用(拷贝)构造函数,因为构造函数是在构造出对对象之前,此时,对象是不存在的,因此(拷贝)构造函数是用来创建对象,并不是用于对象的调用。
3.
他也默认传入了 * const this指针,同时拷贝构造函数必须传入对象的引用或者指针,不能进行值传递(也就是不能直接传对象)
这个问题,大部分的人只是很浅层次的知道它会产生死递归!那么究竟为什么呢???????看下面的四。
四:拷贝构造函数做了哪些事情?
它在参数传递地过程中到底做了什么事呢?
由于其实引用的底层也是用const指针来实现的也就是地址传递,而对于值传递和地址传递统一起来归根结底还是“值”传递,(地址也是值)
i:值传递
①对于内置类型的传递时,直接赋值拷贝给形参(注意:形参是函数的局部变量)
②对于 类 类型的传递时,需要调用该类的拷贝构造函数来初始化形参(局部对象,临时对象){这就是会产生死递归的原因}
j:无论是值内置类型还是类类型,引用或者指针最终传递的 是 地址值!!!地址值属于简单类型,显然传参时按照简单类型的赋值拷贝参数时,不会调用拷贝构造函数。
所以这也是为什么拷贝构造函数参数传递的是引用或指针,而不是直接的值传递
五:代码案例
typedef class Cgoods
{
public:
//...
private:
char *_name;
int _num;
double _price;
}Cgoods,*PCgoods;
Cgoods (Cgoods &good)
{
_name = new char [strlen(good._name)+1];//为了重新获取一块不同的heap的空间资源
strncpy(_name,good._name,strlen(good._name+1));
_num = good._num;
_price = good._price;
}
void main()
{
//调用方式
Cgoods good1 = ("shangpin1",2,25.00);
//1
Cgoods good2 = good1;
//2
Cgoods good3(good1);
}