拷贝构造函数是一种特殊的构造函数,遵循如下的规则:
1.函数名和类名一致,没有返回值。
2.必须有一个参数,参数是本类型的一个引用变量。
3.拷贝构造函数可以访问参数对象的任意成员(private也可以)。
4.若自己不提供拷贝构造函数,系统会提供默认构造函数,若自己定义,系统将不再提供。
5.系统提供的拷贝构造是浅拷贝。
书写示例如下:
1 2 3 4 5 6 7 8 9 10 11 12
| class Student { public: //构造函数 Student(int a, char* p); //拷贝构造函数 Student(const Student& stu); char name[32]; int age; };
|
拷贝构造函数调用
1 2 3 4 5 6 7
| //调用方法1 Object obj1; Object obj2(obj1); //或者写成:Object obj2 = obj1;
//调用方法2 Object obj1; Object* obj2 = new Object(obj1);
|
浅拷贝
浅拷贝不开辟新空间,只增加一个指针,指向原有的内存。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include <iostream> using namespace std; class Student { public: //构造函数 Student(const char* myName) { int len = strlen(myName); name = new char[len + 1]{0}; strcpy_s(this->name, len+1, myName); cout << "构造:" << hex << (int)name << endl; } //析构函数 ~Student() { if (name) { cout << "析构:" << hex << (int)name << endl; delete[] name; name = NULL; } } //拷贝构造函数(浅拷贝) Student(const Student& stu) { name = stu.name; cout << "调用拷贝构造函数" << endl; } private: char* name; }; int main() { { Student stu1("hongshaorou"); Student stu2(stu1); } }
|
运行过程中发生了崩溃
是因为对相同的内存地址做了两次析构导致,打印出内存地址一目了然。
深拷贝
深拷贝会开辟新的内存空间,把原有的对象复制过来。见下图:
对上边浅拷贝代码进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Student { public: //构造函数 Student(const char* myName) { int len = strlen(myName); name = new char[len + 1]{0}; strcpy_s(this->name, len+1, myName); cout << "构造:" << hex << (int)name << endl; } //析构函数 ~Student() { if (name) { cout << "析构:" << hex << (int)name << endl; delete[] name; name = NULL; } } //拷贝构造函数(深拷贝) Student(const Student& stu) { int len = strlen(stu.name); name = new char[len + 1]; strcpy_s(name, len + 1, stu.name); cout << "调用拷贝构造函数" << hex << (int)name<< endl; } private: char* name; };
|
再次运行不会发生崩溃现象,打印内存地址可见,开辟了内存空间。