亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++深淺拷貝淺析

2019-11-06 06:08:45
字體:
來源:轉載
供稿:網(wǎng)友

 C++中深拷貝和淺拷貝的問題是很值得我們注意的知識點,如果編程中不注意,可能會出現(xiàn)疏忽,導致bug。本文就詳細講講C++深淺拷貝的種種。

       對于一般的對象,如:

C++代碼int a = 10;   int b = 20;  

       它們之間的賦值、復制過程是很簡單的。但是對于類對象來說,其內(nèi)部存在各種類型成員變量,在拷貝過程中會出現(xiàn)問題。如下:

C++代碼#include<iostream>    #include<cstring>    using namespace std;    class String {    public:        String (const char* psz=NULL) : m_psz(strcpy((new char[strlen(psz?psz:"")+1]),psz?psz:"")){            cout << "String構造" << endl;        }         ~String () {            if(m_psz) {                 delete[] m_psz;                 m_psz = NULL;            }            cout << "String析構" << endl;        }        char* c_str(void) {            return m_psz;        }    PRivate:        char* m_psz;    };    int main(void) {        String s1("hello");        String s2(s1);        cout << "s1    " << s1.c_str() << endl;        cout << "s2    " << s2.c_str() << endl;        s1.c_str()[0] = 'H';        cout << "s1    " << s1.c_str() << endl;        cout << "s2    " << s2.c_str() << endl;        return 0;    }  

       運行結果:

C++深淺拷貝淺析

       編譯通過了,運行后出現(xiàn)一堆的錯誤,為什么?!這就是淺拷貝帶來的問題。

       事實是,在對象拷貝過程中,如果沒有自定義拷貝構造函數(shù),系統(tǒng)會提供一個缺省的拷貝構造函數(shù),缺省的拷貝構造函數(shù)對于基本類型的成員變量,按字節(jié)復制,對于類類型成員變量,調(diào)用其相應類型的拷貝構造函數(shù)。原型如下:

C++代碼String (const String& that) {}  

       但凡是編譯系統(tǒng)提供的缺省函數(shù),總不是十全十美的。

       缺省拷貝構造函數(shù)在拷貝過程中是按字節(jié)復制的,對于指針型成員變量只復制指針本身,而不復制指針所指向的目標--淺拷貝。

       用下圖來解釋這個問題:

C++深淺拷貝淺析

       在進行對象復制后,事實上s1、s2里的成員指針m_psz都指向了一塊內(nèi)存空間(即內(nèi)存空間共享了),在s1析構時,delete了成員指針m_psz所指向的內(nèi)存空間,而s2析構時同樣指向(此時已變成野指針)并且要釋放這片已經(jīng)被s1析構函數(shù)釋放的內(nèi)存空間,這就讓同樣一片內(nèi)存空間出現(xiàn)了“double free” ,從而出錯。而淺拷貝還存在著一個問題,因為一片空間被兩個不同的子對象共享了,只要其中的一個子對象改變了其中的值,那另一個對象的值也跟著改變了,正如程序中只改變了s1.c_str()[0] = 'H',然而輸出的s1,s2均為hello,所以這并不是真正意義上的復制。

       為了實現(xiàn)深拷貝,往往需要自己定義拷貝構造函數(shù),在源代碼里,我們加入自定義的拷貝構造函數(shù)如下:

C++代碼String (const String& that) : m_psz(strcpy((new char[strlen(that.m_psz)+1]),that.m_psz)){       cout << "String拷貝構造" << endl;   }  

       這樣再運行就沒有問題了。

       在程序中,還有哪些情況會用到拷貝構造函數(shù)呢?當函數(shù)存在對象型的參數(shù)或對象型的返回值時都會用到拷貝構造函數(shù)。

       而拷貝賦值的情況基本上與拷貝復制是一樣的。只是拷貝賦值是屬于操作符重載問題。例如在主函數(shù)若有:String s3;s3 = s2;這樣系統(tǒng)在執(zhí)行時會調(diào)用系統(tǒng)提供的缺省的拷貝賦值函數(shù),原型如下:

C++代碼void Operator = (const String& that) {}  

       我們可以自定義拷貝賦值函數(shù)如下:

C++代碼void operator=(const String& that) {       m_psz = strcpy (new char[strlen(that.m_psz)+1],that.m_psz);   }  

       但是這只是新手級別的寫法,考慮的問題太少。我們知道對于普通變量來講a=b返回的是左值a的引用,所以它可以作為左值繼續(xù)接收其他值(a=b)=30,這樣來講我們操作符重載后返回的應該是類對象的引用(否則返回值將不能作為左值來進行運算),如下:

C++代碼String& operator=(const String& that){       m_psz = strcpy (new char[strlen(that.m_psz)+1],that.m_psz);   }  

       而 m_psz = strcpy (new char[strlen(that.m_psz)+1],that.m_psz);這種寫法其實也有問題,因為在執(zhí)行語句時,m_psz已經(jīng)被構造已經(jīng)分配了內(nèi)存空間,但是如此進行指針賦值,m_psz直接轉而指向另一片新new出來的內(nèi)存空間,而丟棄了原來的內(nèi)存,這樣便造成了內(nèi)存泄露。應更改為:

C++代碼String& operator=(const String& that) {       delete[] m_psz;       m_psz = strcpy (new char[strlen (that.m_psz)+1],that.m_psz);   }  

       這樣就行了嗎?在這個世界上不怕沒好事就怕沒好人,萬一他跟你搞一個自賦值(s3=s3)怎么辦?

       操作符左右兩邊都是同一個對象,這樣先delete[] m_psz,后面又有that.m_psz,這就出現(xiàn)了問題。所以為了防止自賦值,我們一般的寫法為:

C++代碼String& operator=(cosnt String& that) {       if(&that != this) {           delete[] m_psz;           m_psz = strcpy (new char[strlen(that.m_psz)+1],that.m_psz);          }       return *this;   }  

       可是這樣寫就完善了嗎?是否要再仔細思索一下,還存在問題嗎?!其實我可以告訴你,這樣的寫法也頂多算個初級工程師的寫法。前面說過,為了保證內(nèi)存不泄露,我們前面delete[] m_psz,然后我們在把new出來的空間給了m_psz,但是這樣的問題是,你有考慮過萬一new失敗了呢?!內(nèi)存分配失敗,m_psz沒有指向新的內(nèi)存空間,但是它卻已經(jīng)把舊的空間給扔掉了,所以顯然這樣的寫法依舊存在著問題。一般高級工程師的寫法會是這樣的:

C++代碼String& operator=(cosnt String& that) {        if(&that != this) {            char *psz = strcpy (new char[strlen(that.m_psz)+1],that.m_psz);//如果失敗會拋出異常,m_psz最后在析構函數(shù)里釋放            delete[] m_psz;            m_psz = psz;           }        return *this;    }  

       這樣考慮的問題便比較全面了。

       高級工程師高確實高,然而有沒有比高級工程師更高的工程師呢?答案是肯定的。對于從事多年C++開發(fā)元老級別資深的C++工程師來講,他們不會這么寫,因為有更好更簡便的寫法,如下:

C++代碼String& operator=(const String& that) {        if(&that != this) {            String str (that);            char *psz = m_psz;            m_psz = str.m_psz;            str.m_psz = psz;        }        return *this;    }  

       有人看出來這樣寫的玄機了嗎??

       事實上,這是借助了以上自定義的拷貝構造函數(shù)。定義了局部對象str,在拷貝構造中已經(jīng)為str的成員指針分配了一塊內(nèi)存,所以只需要將str.m_psz與this->m_psz交換指針即可,簡化了程序的設計,因為str是局部對象,離開作用域會調(diào)用析構函數(shù)釋放交換給str.m_psz的內(nèi)存,避免了內(nèi)存泄露。

       大家在讀完這篇文章后,對于C++的代碼設計,是否有一定的感悟了呢?在我們進行C++的代碼設計的過程中,一定要多加思索,考慮問題要全面,精益求精,寫出來的代碼才經(jīng)得住推敲!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表

圖片精選

欧美高清激情视频| 欧美电影完整版在线观看| 美女网站免费看| 男女羞羞视频教学| 久久久免费看片| 国产精品9999久久久久仙踪林| 天堂а√在线中文在线| 免费高清视频日韩| 亚洲911精品成人18网站| 99久久精品国产亚洲精品| 国产在线综合网| 国内欧美视频一区二区| 九九九伊在人线综合| 天天操天天干天天干| 中文字幕一区二区久久人妻网站| 亚洲永久字幕| 一本色道综合久久欧美日韩精品| 偷拍视频一区二区| 日韩精品影音先锋| 亚洲国产欧美一区| 亚洲一区精品电影| 成人高清免费| 国产成a人亚洲精v品在线观看| caoporm在线视频| 一区二区在线观看免费视频播放| 丰满少妇又爽又紧又丰满69| 深夜福利视频在线观看| 午夜肉伦伦影院| 草草视频在线播放| 伊人免费在线观看高清版| 成人免费淫片免费观看| www视频在线| 99精品视频在线观看播放| 性生生活性生交a级| 精品第一国产综合精品aⅴ| 西野翔中文久久精品字幕| 国产麻豆永久视频| 国产传媒在线视频| 一区二区三区精品在线观看| 一区二区三区日韩精品| av不卡在线播放| 国产精品9区| 亚洲国产成人午夜在线一区| 亚洲精品午夜国产va久久成人| 亚乱亚乱亚洲乱妇| 中国一级大黄大黄大色毛片| 日韩免费高清视频网站| 欧美男人操女人视频| 国产精品12| 性生活免费观看视频| 日本网站免费在线观看| 欧美性生活一级片| 国产精品久免费的黄网站| 另类国产ts人妖高潮视频| 狠狠色狠狠色综合日日tαg| 青青草在线观看视频| 日本国产中文字幕| 亚洲一级黄色片| 97人人做人人爱| 在线观看国产一区| 97成人资源站| 亚洲综合大片69999| xxxxx成人.com| 欧美日韩亚洲视频一区| 黄色aaa大片| 成人影院www在线观看| 极品粉嫩饱满一线天在线| 精品免费国产| 成人一区二区三| 欧美日韩性视频一区二区三区| 欧美乱强性伦xxxxx| 日本午夜一区二区三区| 久久精品视频99| 亚洲专区欧美专区| 日本免费久久高清视频| 韩日精品一区| 琪琪久久久久日韩精品| 日本中文字幕一区二区视频| 亚洲色图美腿丝袜| 亚洲国产小视频在线观看| 国产精品99一区二区三| 欧美视频三区在线播放| 好男人社区在线视频| 麻豆av免费看| 国产激情视频一区二区| 久久99精品久久久久久欧洲站| 日韩黄色小视频| 丝袜美腿中文字幕| 美女视频第一区二区三区免费观看网站| 精品人妻二区中文字幕| 97精品国产一区二区三区| 日本在线啊啊| 久在线观看视频| 欧美一区二区福利在线| 国产精品45p| 欧美老少做受xxxx高潮| 欧美成人性战久久| 亚洲福利电影| 69ww免费视频播放器| 欧美性xxxx极品高清hd直播| 国产精品爽爽久久久久久| 全彩无遮挡全彩口工漫画h#| 人妻少妇精品久久| 欧美日韩一本到| 久久久久女人精品毛片九一| 日本三级午夜理伦三级三| 欧美aaaaa级| 1024成人网| 成人观看网站a| 亚洲精品第一| 婷婷久久综合九色综合99蜜桃| 黄色成人在线视频| 久久精品欧美一区二区| 国产成人丝袜美腿| 狠狠躁夜夜躁av无码中文幕| 精品国产乱码一区二区三区| 午夜视频在线观看一区二区三区| 久久久久人妻一区精品色欧美| 美女网站一区二区| 国产精品扒开腿做爽爽爽软件| 精品免费av| 麻豆视频一区二区| 一级爱爱免费视频| 激情丁香婷婷| 欧美连裤袜在线视频| 欧美5-7sexvideos处| 99riav在线| 无码aⅴ精品一区二区三区浪潮| 91freevideo| 亚洲视频自拍| 亚洲一区二区三区日本久久九| youjizz.com亚洲| 奇米影视亚洲狠狠色| 国产精品免费视频一区二区三区| 亚洲精品专区| 久久久久久久9| 日韩精品视频免费看| 99香蕉久久| 国产一区二区三区在线| 亚洲一区有码| 成人黄色片免费| 成人免费在线观看网站| 天天躁日日躁狠狠躁免费麻豆| 亚洲已满18点击进入久久| 99在线视频精品| 精品国产一二三四区| www.一区二区| 国产成人精品免费看视频| 欧美久久久一区| 中文字幕久久网| 少妇视频在线播放| 在线电影院国产精品| 上原亚衣加勒比在线播放| 欧美第一黄色网| 精品国产老师黑色丝袜高跟鞋| 人妻无码视频一区二区三区| 精品久久久久久久久久久久久久久久| 久久影院一区二区三区| 欧美婷婷精品激情| 精品一区二区三区日韩| 亚洲欧美日韩激情| 亚洲 国产 日韩 欧美| 香蕉网站在线| 国产精品狼人色视频一区| 日韩精品在线一区二区三区| 国产在线精品一区二区三区》| 天堂资源在线视频| 四虎成人影院网址| 蜜臀久久99精品久久久久久| 成人动漫视频在线观看| av大片免费在线观看| 国产免费中文字幕| 中日精品一色哟哟| 狠狠躁日日躁夜夜躁av| 欧美电影免费观看网站| 国产劲爆久久| 在线网址91| 国产99精品在线观看| 色姑娘综合天天| 超碰中文字幕在线观看| 欧美aaaaa成人免费观看视频| 成人免费视频国产在线观看| 亚洲一区二区自拍偷拍| 黄色综合网址| 超碰精品在线| 国产极品美女到高潮| 91jq激情在线观看| 日本午夜精品理论片a级appf发布| 99re国产视频| av在线网址导航| 成人免费视频在线观看超级碰| 中国日韩欧美久久久久久久久| 久久黄色网页| 国产精品自拍视频在线| 久久久久成人片免费观看蜜芽| 欧美日韩三级在线| 色呦呦一区二区| 色噜噜成人av在线| 欧美午夜精品一区二区三区电影| av蜜臀在线| 精品成在人线av无码免费看| 先锋影音成人资源| 影音先锋日韩资源| 日日夜夜天天综合| 亚洲综合欧美| 三级成人黄色影院| 星空影院最新电视剧免费观看| 亚洲色图21p| 91嫩草在线视频| 亚洲国产网址| 国产精品传媒入口麻豆| 色开心亚洲综合| 99re成人在线| 欧美精品黑人猛交高潮| 免费观看成人在线视频| 中文字幕 日韩有码| 国产亚洲第一区| 亚洲女同av| 久久久久久九九九九九| av中文在线资源| 国产精彩视频在线观看免费蜜芽| 麻豆av一区二区三区| 日韩高清在线播放| 中文字幕在线不卡视频| 免费av网站在线观看| 精品日韩在线一区| 亚洲成av人**亚洲成av**| 亚洲国产成人一区二区三区| www.91在线| 狠狠躁夜夜躁av无码中文幕| 国产呦系列欧美呦日韩呦| 中文字幕中文字幕中文字幕亚洲无线| 中文字幕一区二区三区在线乱码| www.色国产| 国产日韩精品视频一区二区三区| 久久综合久久鬼色| 免费中文字幕日韩| 黄瓜视频成人app免费| 熟妇人妻中文av无码| 亚洲怡红院av| 国内成人精品一区| 卡通动漫精品一区二区三区| 久久久www成人免费无遮挡大片| 精品视频高潮| 欧美日韩系列| 国产乱码精品一区二区三| 亚洲欧洲另类| 丁香久久综合| 天天操天天舔天天射| 久久99久久99精品免观看粉嫩| 国产精品 日产精品 欧美精品| 国产精品nxnn| 亚洲综合色在线| 亚洲午夜视频在线| 国产午夜福利精品| 久久久精品2019中文字幕神马| 久久久美女艺术照精彩视频福利播放| 久久亚洲国产精品日日av夜夜| 老牛嫩草一区二区三区日本| 九色在线播放| 国产视频中文字幕在线观看| www.4hu95.com四虎| 欧美成人短视频| 精品国产乱码久久久久久影片| 一区二区三区|亚洲午夜| 精品一区二区三区免费毛片| 特黄aaaaaaaaa毛片免费视频| 神马电影网我不卡| 日本午夜精品理论片a级appf发布| 操人真爽免费视频| 国产网友自拍视频导航网站在线观看| 久久精品女人毛片国产| 少妇久久久久久| 成人黄色片在线| 精品久久久久久一区二区里番| 欧美性色欧美a在线播放| 天天操夜夜爽| 亚洲黄色av网站| se01亚洲视频| 老司机激情视频| 色噜噜狠狠永久免费| 美女少妇一区二区| 国产自产视频| 先锋资源中文字幕| 欧美三级美国一级| 成人在线视频一区二区| 日本 国产 欧美色综合| 久久久久久99| 中文字幕欧美日韩va免费视频| 熟妇人妻久久中文字幕| 黑人精品视频| 18精品爽视频在线观看| 久久久999精品| 无码人妻精品一区二区中文| 不卡精品视频| 乱小说综合网站| 男人天堂电影网| 波多野结衣免费观看| 欧美私模裸体表演在线观看| 日韩视频在线你懂得| 天堂在线中文字幕| 欧美tickling网站挠脚心| 国产传媒欧美日韩成人精品大片| 色88久久久久高潮综合影院| 91在线小视频| 日韩欧美三级在线观看| 亚洲天堂免费| 肉丝美足丝袜一区二区三区四| 人人做人人爽人人爱| 国产精品女主播av| 亚洲最新无码中文字幕久久| 7777精品久久久大香线蕉小说| 三级国产三级在线| 欧美成人精品三级网站| 黄页免费在线观看| 日韩精品中文字幕第1页| 日韩高清一区在线| 欧美 国产 日本| 天天亚洲美女在线视频| 日韩一区二区三| 99久久99久久精品免费观看| 日韩毛片一二三区| 不卡一区中文字幕| 欧美日韩精品电影| 国产深夜福利| 国产在线观看免费视频今夜| 亚洲国产经典视频| 欧美这里只有精品|