关于c++深拷贝与浅拷贝

首先看一段代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<malloc.h>
 4 using namespace std;
 5 
 6 class Teacher{
 7 public:
 8     Teacher(int id,char *name){
 9         m_id=id;
10 
11         m_name=(char*)malloc(strlen(name)+1);//由于显示析构函数中free内存空间,因而必须malloc
12         strcpy(m_name,name);
13     }
14 
15     void Print(){
16         cout<<"id="<<m_id<<" name="<<m_name<<endl;
17     }
18 
19     ~Teacher(){/*显示析构函数*/
20         cout<<"Teacher()..."<<endl;
21         if(m_name!=NULL){
22             free(m_name);
23             m_name=NULL;
24         }
25     }
26 private:
27     int m_id;
28     char *m_name;
29 };
30 
31 int main(){
32     Teacher t1(1,"zhangsan");
33     t1.Print();
34 
35     return 0;
36 }

浅谈析构函数特点:

1.函数名是在类名前加上~,无参数且无返回值。

2.一个类只能有且有一个析构函数,如果没有显式的定义,系统会生成一个缺省的析构函数(合成析构函数)。

3.析构函数不能重载。每有一次构造函数的调用就会有一次析构函数的调用。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<malloc.h>
 4 using namespace std;
 5 
 6 class Teacher{
 7 public:
 8     Teacher(int id,char *name){
 9         cout<<"Teacher(int,char*)..."<<endl;
10         m_id=id;
11 
12         int len=strlen(name);
13         m_name=(char*)malloc(len+1);//由于显示析构函数中free内存空间,因而必须malloc
14         strcpy(m_name,name);
15     }
16     /*默认拷贝构造函数,浅拷贝!!!*/
17     Teacher(const Teacher& another){
18         m_id=another.m_id;
19         m_name=another.m_name;
20     }
21     void Print(){
22         cout<<"id="<<m_id<<" name="<<m_name<<endl;
23     }
24 
25     ~Teacher(){/*显示析构函数*/
26         cout<<"Teacher()..."<<endl;
27         if(m_name!=NULL){
28             free(m_name);
29             m_name=NULL;
30         }
31     }
32 private:
33     int m_id;
34     char *m_name;
35 };
36 
37 void test(){
38     Teacher t1(1,"xiaoming");
39     t1.Print();
40 
41     Teacher t2(t1);//t2的默认拷贝构造
42     t2.Print();
43 }
44 
45 int main(){
46     test();
47 
48     return 0;
49 }

【浅拷贝】是增加了一个指针,指向原来已经存在的内存。

而【深拷贝】是增加了一个指针,并新开辟了一块空间,让指针指向这块新开辟的空间

在test函数结束时,t1和t2都会走一遍析构函数,释放内存空间,t2后执行,因而先走析构函数,将name的内存空间释放掉,当t1走析构函数时,会再次进行m_name的内存空间释放,但由于这块内存空间在t2走析构函数时已经被释放掉了,所以在这里会引发段错误!!!,这也就是浅拷贝的危害。。。

为了避免浅拷贝引发的段错误,因而我们需要进行深拷贝,重写拷贝构造函数

 1 #include<iostream>
 2 #include<cstring>
 3 #include<malloc.h>
 4 using namespace std;
 5 
 6 class Teacher{
 7 public:
 8     Teacher(int id,char *name){
 9         cout<<"Teacher(int,char*)..."<<endl;
10         m_id=id;
11 
12         int len=strlen(name);
13         m_name=(char*)malloc(len+1);//由于显示析构函数中free内存空间,因而必须malloc
14         strcpy(m_name,name);
15     }
16     /*重写拷贝构造函数,深拷贝*/
17     Teacher(const Teacher& another){
18         m_id=another.m_id;
19         //深拷贝//
20         int len=strlen(another.m_name);
21         m_name=(char*)malloc(len+1);
22         strcpy(m_name,another.m_name);
23     }
24     void Print(){
25         cout<<"id="<<m_id<<" name="<<m_name<<endl;
26     }
27 
28     ~Teacher(){/*显示析构函数*/
29         cout<<"Teacher()..."<<endl;
30         if(m_name!=NULL){
31             free(m_name);
32             m_name=NULL;
33         }
34     }
35 private:
36     int m_id;
37     char *m_name;
38 };
39 
40 void test(){
41     Teacher t1(1,"xiaoming");
42     t1.Print();
43 
44     Teacher t2(t1);//t2的默认拷贝构造
45     t2.Print();
46 }
47 
48 int main(){
49     test();
50 
51     return 0;
52 }

猜你喜欢

转载自www.cnblogs.com/Bravewtz/p/10333497.html