1.什么是拷贝构造函数?
参数是类对象本身的引用,用已存在的对象复制出一个新的该类的对象,一般的是将已存在对象的数据成员复制到新类的数据成员中。
当数据成员是指针的时候,此时存在浅拷贝和深拷贝。
2.浅拷贝和深拷贝
深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响。
Internet(Internet &temp)
{
cout<<"载入COPY构造函数"<<ENDL;
strcpy(Internet::name,temp.name);
strcpy(Internet::address,temp.address);
cname=newchar[strlen(name)+1];//这里注意,深拷贝的体现!
if(cname!=NULL)
{
strcpy(Internet::cname,name);
}
}
对对象b的cname属性采取了新开辟内存的方式避免了内存归属不清所导致析构释放空间时候的错误,
浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同)。对其中任何一个对象的改动都会影响另外一个对象。
浅拷贝就是上面复制对象的时候调用默认拷贝构造函数,使两个对象的字符指针指向了内存的同一块区域
3.在函数中返回自定义类型对象
Internet tp()
{
Internet b("中国软件开发实验室","www.cndev-lab.com");
returnb;
}
voidmain()
{
Internet a;
a=tp();
}
从上面的代码运行结果可以看出,程序一共载入过析构函数三次,证明了由函数返回自定义类型对象同样会产生临时变量,事实上对象a得到的就是这个临时Internet类类型对象temp的值。
4 无名对象
利用无名对象初始化对象系统不会不调用拷贝构造函数。
那么什么又是无名对象呢?
很简单,如果在上面程序的main函数中有:
Internet("中国软件开发实验室","www.cndev-lab.com");
这样的一句语句就会产生一个无名对象,无名对象会调用构造函数但利用无名对象初始化对象系统不会不调用拷贝构造函数!
voidmain()
{
Internet a=Internet("中国软件开发实验室","www.cndev-lab.com");
cout<<cin.get();//类的成员函数
}
上面代码的运行结果有点“出人意料”,从思维逻辑上说,当无名对象创建了后,是应该调用自定义拷贝构造函数,或者是默认拷贝构造函数来完成复制过程的,但事实上系统并没有这么做,因为无名对象使用过后在整个程序中就失去了作用,对于这种情况c++会把代码看成是:
Internet a("中国软件开发实验室","www.cndev-lab.com");
省略了创建无名对象这一过程,所以说不会调用拷贝构造函数。
5.引用无名对象
voidmain()
{
Internet &a=Internet("中国软件开发实验室","www.cndev-lab.com");
cout<<A.NAME;
cin.get();
}
引用本身是对象的别名,和复制并没有关系,所以不会调用拷贝构造函数,但要注意的是,在c++看来:
Internet &a=Internet("中国软件开发实验室","www.cndev-lab.com");
是等价与:
Internet a("中国软件开发实验室","www.cndev-lab.com");