關於c++深拷貝與淺拷貝
阿新 • • 發佈:2019-01-29
using 釋放 ios ngs not 這也 void 圖片 指向
首先看一段代碼:
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 12strcpy(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 }
關於c++深拷貝與淺拷貝