C++簡(jiǎn)明圖解分析淺拷貝與深拷貝
類中有指針成員 才會(huì)討論 淺拷貝 和深拷貝問(wèn)題。
淺拷貝(單純值拷貝)
#include <iostream> #include <string.h> #include <stdlib.h> using namespace std; class Person { public: char *m_name; public: Person(char *name) { cout<<"有參構(gòu)造"<<endl; m_name = (char *)calloc(1,strlen(name)+1); if(m_name == NULL) { cout<<"空間申請(qǐng)失敗"<<endl; exit(-1); } strcpy(m_name, name); } ~Person() { cout<<"析構(gòu)函數(shù)"<<endl; //釋放指針成員 指向的堆區(qū)空間 if(m_name != NULL) { free(m_name); m_name = NULL; } cout<<"-----001------"<<endl; } }; int main(int argc, char *argv[]) { Person ob1("lucy"); Person ob2 = ob1;//拷貝構(gòu)造(默認(rèn)是淺拷貝) cout<<"ob2.m_name = "<<ob2.m_name<<endl; return 0; }
深拷貝
必須在拷貝構(gòu)造中給ob2.m_name申請(qǐng)空間
#include <iostream> #include <string.h> #include <stdlib.h> using namespace std; class Person { public: char *m_name; public: Person(char *name) { cout<<"有參構(gòu)造"<<endl; m_name = (char *)calloc(1,strlen(name)+1); if(m_name == NULL) { cout<<"空間申請(qǐng)失敗"<<endl; exit(-1); } strcpy(m_name, name); } Person(const Person &ob) { cout<<"拷貝構(gòu)造函數(shù)(深拷貝)"<<endl; m_name = (char *)calloc(1, strlen(ob.m_name)+1); if(m_name == NULL) { cout<<"空間申請(qǐng)失敗"<<endl; exit(-1); } strcpy(m_name, ob.m_name); } ~Person() { cout<<"析構(gòu)函數(shù)"<<endl; //釋放指針成員 指向的堆區(qū)空間 if(m_name != NULL) { free(m_name); m_name = NULL; } } }; int main(int argc, char *argv[]) { Person ob1("lucy"); Person ob2 = ob1;//拷貝構(gòu)造 cout<<"ob2.m_name = "<<ob2.m_name<<endl; return 0; }
總結(jié)
1、如果類中的成員 指向了堆區(qū)空間 一定要記得在析構(gòu)函數(shù)中 釋放該空間
2、如果用戶 不實(shí)現(xiàn) 拷貝構(gòu)造 系統(tǒng)就會(huì)提供默認(rèn)拷貝構(gòu)造,而默認(rèn)拷貝構(gòu)造 只是單純的賦值 容易造成淺拷貝問(wèn)題
3、用戶記得 要實(shí)現(xiàn):無(wú)參構(gòu)造(初始化數(shù)據(jù))、有參構(gòu)造(賦參數(shù))、拷貝構(gòu)造(深拷貝) 、析構(gòu)函數(shù)(釋放空間)
拷貝構(gòu)造函數(shù)的調(diào)用時(shí)機(jī)
拷貝構(gòu)造函數(shù)調(diào)用的時(shí)機(jī):舊對(duì)象 給新對(duì)象 初始化
class Data { public: Data() { cout<<"無(wú)參構(gòu)造"<<endl; } Data(const Data &ob) { cout<<"拷貝構(gòu)造"<<endl; } ~Data() { cout<<"析夠函數(shù)"<<endl; } };
情形1:舊對(duì)象給新對(duì)象初始化
Data ob1; Data ob2 = ob1;//調(diào)用拷貝構(gòu)造
情形2:普通對(duì)象作為函數(shù)的參數(shù)
void fun01(Data ob)//Data ob=ob1 發(fā)生拷貝構(gòu)造 { } int main(int argc, char *argv[]) { Data ob1; fun01(ob1); return 0; }
情形3:普通對(duì)象 作為函數(shù)的返回值
#include <iostream> using namespace std; Data fun01(void) { Data ob1; return ob1; } int main(int argc, char *argv[]) { Data ob = fun01(); return 0; }
vs下會(huì)發(fā)生拷貝構(gòu)造:
Qt、linux不會(huì)發(fā)生拷貝:
到此這篇關(guān)于C++簡(jiǎn)明圖解分析淺拷貝與深拷貝的文章就介紹到這了,更多相關(guān)C++淺拷貝與深拷貝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[二]
C 語(yǔ)言基礎(chǔ)教程(我的C之旅開(kāi)始了)[二]...2007-02-02C++實(shí)現(xiàn)逆波蘭表達(dá)式的例題詳解
逆波蘭表達(dá)式由波蘭的邏輯學(xué)家盧卡西維茲提出,它的特點(diǎn)是:沒(méi)有括號(hào),運(yùn)算符總是放在和它相關(guān)的操作數(shù)之后。本文將通過(guò)例題講講如何利用C++實(shí)現(xiàn)逆波蘭表達(dá)式,需要的可以參考一下2022-12-12C++ Strassen算法代碼的實(shí)現(xiàn)
這篇文章主要介紹了C++ Strassen算法代碼的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03C語(yǔ)言的getc()函數(shù)和gets()函數(shù)的使用對(duì)比
這篇文章主要介紹了C語(yǔ)言的getc()函數(shù)和gets()函數(shù)的使用對(duì)比,從數(shù)據(jù)流中一個(gè)是讀取字符一個(gè)是讀取字符串,需要的朋友可以參考下2015-08-08C語(yǔ)言鏈表實(shí)現(xiàn)工資管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言鏈表實(shí)現(xiàn)工資管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02