一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

C 面試題之淺拷貝和深拷貝的區(qū)別

 心本心123 2021-12-08

       先考慮一種情況,對(duì)一個(gè)已知對(duì)象進(jìn)行拷貝,編譯系統(tǒng)會(huì)自動(dòng)調(diào)用一種構(gòu)造函數(shù)——拷貝構(gòu)造函數(shù),如果用戶(hù)未定義拷貝構(gòu)造函數(shù),則會(huì)調(diào)用默認(rèn)拷貝構(gòu)造函數(shù)。

       先看一個(gè)例子,有一個(gè)學(xué)生類(lèi),數(shù)據(jù)成員時(shí)學(xué)生的人數(shù)和名字:

  1. #include <iostream>
  2. using namespace std;
  3. class Student
  4. {
  5. private:
  6. int num;
  7. char *name;
  8. public:
  9. Student();
  10. ~Student();
  11. };
  12. Student::Student()
  13. {
  14. name = new char(20);
  15. cout << 'Student' << endl;
  16. }
  17. Student::~Student()
  18. {
  19. cout << '~Student ' << (int)name << endl;
  20. delete name;
  21. name = NULL;
  22. }
  23. int main()
  24. {
  25. {// 花括號(hào)讓s1和s2變成局部對(duì)象,方便測(cè)試
  26. Student s1;
  27. Student s2(s1);// 復(fù)制對(duì)象
  28. }
  29. system('pause');
  30. return 0;
  31. }


       執(zhí)行結(jié)果:調(diào)用一次構(gòu)造函數(shù),調(diào)用兩次析構(gòu)函數(shù),兩個(gè)對(duì)象的指針成員所指內(nèi)存相同,這會(huì)導(dǎo)致什么問(wèn)題呢?name指針被分配一次內(nèi)存,但是程序結(jié)束時(shí)該內(nèi)存卻被釋放了兩次,會(huì)導(dǎo)致崩潰!

       這是由于編譯系統(tǒng)在我們沒(méi)有自己定義拷貝構(gòu)造函數(shù)時(shí),會(huì)在拷貝對(duì)象時(shí)調(diào)用默認(rèn)拷貝構(gòu)造函數(shù),進(jìn)行的是淺拷貝!即對(duì)指針name拷貝后會(huì)出現(xiàn)兩個(gè)指針指向同一個(gè)內(nèi)存空間。

       所以,在對(duì)含有指針成員的對(duì)象進(jìn)行拷貝時(shí),必須要自己定義拷貝構(gòu)造函數(shù),使拷貝后的對(duì)象指針成員有自己的內(nèi)存空間,即進(jìn)行深拷貝,這樣就避免了內(nèi)存泄漏發(fā)生。

        添加了自己定義拷貝構(gòu)造函數(shù)的例子:

  1. #include <iostream>
  2. using namespace std;
  3. class Student
  4. {
  5. private:
  6. int num;
  7. char *name;
  8. public:
  9. Student();
  10. ~Student();
  11. Student(const Student &s);//拷貝構(gòu)造函數(shù),const防止對(duì)象被改變
  12. };
  13. Student::Student()
  14. {
  15. name = new char(20);
  16. cout << 'Student' << endl;
  17. }
  18. Student::~Student()
  19. {
  20. cout << '~Student ' << (int)name << endl;
  21. delete name;
  22. name = NULL;
  23. }
  24. Student::Student(const Student &s)
  25. {
  26. name = new char(20);
  27. memcpy(name, s.name, strlen(s.name));
  28. cout << 'copy Student' << endl;
  29. }
  30. int main()
  31. {
  32. {// 花括號(hào)讓s1和s2變成局部對(duì)象,方便測(cè)試
  33. Student s1;
  34. Student s2(s1);// 復(fù)制對(duì)象
  35. }
  36. system('pause');
  37. return 0;
  38. }


        執(zhí)行結(jié)果:調(diào)用一次構(gòu)造函數(shù),一次自定義拷貝構(gòu)造函數(shù),兩次析構(gòu)函數(shù)。兩個(gè)對(duì)象的指針成員所指內(nèi)存不同。
 總結(jié):淺拷貝只是對(duì)指針的拷貝,拷貝后兩個(gè)指針指向同一個(gè)內(nèi)存空間,深拷貝不但對(duì)指針進(jìn)行拷貝,而且對(duì)指針指向的內(nèi)容進(jìn)行拷貝,經(jīng)深拷貝后的指針是指向兩個(gè)不同地址的指針。
再說(shuō)幾句:
當(dāng)對(duì)象中存在指針成員時(shí),除了在復(fù)制對(duì)象時(shí)需要考慮自定義拷貝構(gòu)造函數(shù),還應(yīng)該考慮以下兩種情形:
1.當(dāng)函數(shù)的參數(shù)為對(duì)象時(shí),實(shí)參傳遞給形參的實(shí)際上是實(shí)參的一個(gè)拷貝對(duì)象,系統(tǒng)自動(dòng)通過(guò)拷貝構(gòu)造函數(shù)實(shí)現(xiàn);
2.當(dāng)函數(shù)的返回值為一個(gè)對(duì)象時(shí),該對(duì)象實(shí)際上是函數(shù)內(nèi)對(duì)象的一個(gè)拷貝,用于返回函數(shù)調(diào)用處。

3.淺拷貝帶來(lái)問(wèn)題的本質(zhì)在于析構(gòu)函數(shù)釋放多次堆內(nèi)存,使用std::shared_ptr,可以完美解決這個(gè)問(wèn)題。

關(guān)于std::shared_ptr的原理和實(shí)現(xiàn)可參考:C++筆試題之smart pointer的實(shí)現(xiàn)

一個(gè)完整的自定義類(lèi)實(shí)現(xiàn)可參考:C++筆試題之String類(lèi)的實(shí)現(xiàn)

參考鏈接:https://www.cnblogs.com/always-chang/p/6107437.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    欧美日韩三区在线观看| 日韩精品毛片视频免费看| 亚洲一区二区三区在线中文字幕| 最近中文字幕高清中文字幕无| 91精品视频全国免费| 激情五月天免费在线观看| 日韩偷拍精品一区二区三区| 在线九月婷婷丁香伊人| 亚洲av首页免费在线观看| 国产麻豆一区二区三区在| 不卡视频在线一区二区三区| 国产精品免费无遮挡不卡视频| 久久精品国产99国产免费| 日本不卡在线视频你懂的| 国语久精品在视频在线观看| 正在播放玩弄漂亮少妇高潮| 亚洲中文字幕在线乱码av| 亚洲综合日韩精品欧美综合区| 亚洲欧美日韩色图七区| 欧美精品女同一区二区| 九九热视频免费在线视频| 国产超薄黑色肉色丝袜| 一区二区在线激情视频| 一区二区三区亚洲天堂| 色综合久久六月婷婷中文字幕| 日本成人中文字幕一区| 日韩人妻欧美一区二区久久| 色婷婷日本视频在线观看| 国产欧美高清精品一区| 黄色美女日本的美女日人| 亚洲欧美日韩精品永久| 国产精品亚洲欧美一区麻豆| 91久久精品国产成人| 日韩精品福利在线观看| 国产精品日韩欧美第一页| 日本二区三区在线播放| 少妇淫真视频一区二区| 亚洲精品一区二区三区日韩| 日韩不卡一区二区在线| 人人妻人人澡人人夜夜| 区一区二区三中文字幕|