什么是拷贝构造?
通过已经存在的一个对象创建另外一个对象
拷贝构造函数固定接受一个const的引用为参数。
拷贝构造的调用方式有两种,分别是p2和p3所演示的两种方式。一种是在生成对象的时候将已存在的对象作为一个参数传入。另一种就是使用等号赋值的方式调用
这个是没有显示拷贝构造函数时的情况。在这种情况下,编译器会默认将对象p1中的所有成员变量全部赋值给新对象。当有显示的拷贝构造函数时,就会按照函数的编写来创建对象
----------------------------------------------------------------------------------分割线---------------------------------------------------------------------------------------
粗略介绍拷贝函数之后,下面介绍浅拷贝和深拷贝
什么是浅拷贝?
浅拷贝就是把一个对象中的所有内容拷贝到另一个对象。如果源对象的成员变量中含有指针的话,那么新对象中指针变量的值和源对象中的一样。也就是会存在有两个指针指向同一块内存的情况。
什么是深拷贝?
深拷贝和浅拷贝唯一不同的是,如果遇到指针变量。会将指针变量指向的内容重新拷贝一次。也就是说,浅拷贝只拷贝地址值,深拷贝拷贝的是地址中的内容
PS:编译器默认使用的拷贝函数使用的是浅拷贝。如果想要实现深拷贝,一般需要自行实现、
从这里可以很明显的看出,p1和p2两个对象中,成员变量char* name指针,指向的是同一块内存空间。这样做有潜在的风险存在。
1 #include <iostream> 2 using namespace std; 3 4 class Person { 5 int age; 6 char* name; 7 public: 8 Person(int age = 0,char* name=NULL) :age(age),name(name){} 9 10 /*Person(const Person& p) :age(age) { 11 if (p.name == NULL) 12 return; 13 name = new char[strlen(p.name) + 1]; 14 strcpy_s(name, strlen(p.name)+1 , p.name); 15 }*/ 16 17 /*~Person() { 18 if (name == NULL) 19 return; 20 delete[] name; 21 }*/ 22 23 void info() { 24 cout << "Person::age = " << age << endl; 25 cout << "Person::name = " << name << endl; 26 } 27 28 }; 29 30 int main() { 31 32 char p[] = { 'b','r','u','c','e','\0' }; 33 Person p1(10, p); 34 //p1.info(); 35 36 Person p2 = p1; 37 p2.info(); 38 39 return 0; 40 }
//代码中的注释部分为人工给出的拷贝构造函数
此时使用的是编译器默认给出的浅拷贝构造。为了达到我们的目的,就是两个指针指向不同的内存空间,我们需要自己给出拷贝构造函数。
通过自己给出的拷贝构造方法,我们达到了我们想要的目的。
总结:
什么时候需要使用拷贝构造呢?一般来说,编译器默认给出的前拷贝构造函数基本都能满足我们的需求。但是,当成员变量中出现指针变量时,我们就需要自己重写拷贝构造函数了