深拷贝与浅拷贝

1、浅拷贝

  浅拷贝,为值拷贝(在栈中把值拷贝给另一个变量),当变量为指针时,只是把地址拷贝过来,造成了多个指针指向同一块堆内存,在释放内存时会出现运行异常。

  实例代码如 1 #define _CRT_SECURE_NO_WARNING 2 #include <iostream> 3 #include<cstdlib> 4

 5 using namespace std;
 6 
 7 class Teacher {
 8 public:
 9     Teacher(int id, char *name) {
10         cout << "Teacher(int,char*)..." << endl;
11         m_id = id;
12         int len = strlen(name);
13         m_name = (char*)malloc(len + 1);//因为这是C语言函数,它会在结尾增加\0,所以要加一个字节
14         //C语言中'\0'为转义字符,为字符串结束标志。
15         strcpy(m_name, name);
16     }
17     void print_t() {
18         cout << "id=" << m_id << ",name=" << m_name << endl;
19     }
20     //显示的提供一个拷贝构造函数
21     Teacher(const Teacher &another) {
22         m_id = another.m_id;
23         m_name = another.m_name;//此为浅拷贝,为值拷贝(在栈中把值拷贝给另一个变量),当变量为指针时,只是把地址拷贝过来。

    }
28 29 ~Teacher() { 30 cout << "~Teacher()" << endl; 31 if (m_name != NULL) { 32 free(m_name); 33 m_name = NULL; 34 } 35 } 36 private: 37 int m_id; 38 char *m_name; 39 }; 40 41 void test() { 42 Teacher t1(1, "zhang3"); 43 t1.print_t(); 44 45 Teacher t2(t1);//调用t2的默认拷贝构造函数 46 t2.print_t(); 47 } 48 int main(void) { 49 test(); 51 system("pause"); 52 return 0; 53 }

  上面代码运行会报错,原因是,浅拷贝中t2的char *name与t1的指向同一个堆中地址,(后构造的先析构)当t2调用完毕后会调用析构函数销毁堆中内存占用(name=NULL);

  然后在t1调用析构函数时,name指向的空间已经释放,所以运行报错。

  

2、深拷贝

  重新开辟内存空间,把上代码中的拷贝构造函数修改如下:

1 //显示的提供一个拷贝构造函数,来完成深拷贝动作(定义一个深拷贝)
2     Teacher(const Teacher &another) {
3         m_id = another.m_id;
4         //m_name = another.m_name;//此为浅拷贝
5         int len = strlen(another.m_name);
6         m_name = (char*)malloc(len + 1);
7         strcpy(m_name, another.m_name);
8     }

  深拷贝为t2的name在堆中开辟了新的空间,在调用各自析构函数时各自释放各自的空间,代码正常运行。

posted @ 2018-12-01 21:27  zarjen  阅读(154)  评论(0编辑  收藏  举报