小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 心本心123 2021-12-08

       先考慮一種情況,對一個已知對象進行拷貝,編譯系統(tǒng)會自動調用一種構造函數(shù)——拷貝構造函數(shù),如果用戶未定義拷貝構造函數(shù),則會調用默認拷貝構造函數(shù)。

       先看一個例子,有一個學生類,數(shù)據(jù)成員時學生的人數(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. {// 花括號讓s1和s2變成局部對象,方便測試
  26. Student s1;
  27. Student s2(s1);// 復制對象
  28. }
  29. system('pause');
  30. return 0;
  31. }


       執(zhí)行結果:調用一次構造函數(shù),調用兩次析構函數(shù),兩個對象的指針成員所指內存相同,這會導致什么問題呢?name指針被分配一次內存,但是程序結束時該內存卻被釋放了兩次,會導致崩潰!

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

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

        添加了自己定義拷貝構造函數(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);//拷貝構造函數(shù),const防止對象被改變
  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. {// 花括號讓s1和s2變成局部對象,方便測試
  33. Student s1;
  34. Student s2(s1);// 復制對象
  35. }
  36. system('pause');
  37. return 0;
  38. }


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

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

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

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

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

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多