<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] 參考鏈接:[https://blog.csdn.net/caoshangpa/article/details/79226270](https://blog.csdn.net/caoshangpa/article/details/79226270) ### 舉個例子 ***** 有一個學生類,數據成員是學生人數和名字: ``` #include <iostream> using namespace std; class Student { private: int num; char *name; public: Student(); ~Student(); }; Student::Student() { name = new char(20); cout << "Student" << endl; } Student::~Student() { cout << "~Student " << (int)name << endl; delete name; name = NULL; } int main() { {// 花括號讓s1和s2變成局部對象,方便測試 Student s1; Student s2(s1);// 復制對象 } system("pause"); return 0; } ``` 執行結果:調用一次構造函數,調用兩次析構函數,兩個對象的指針成員所指內存相同,這會導致什么問題呢?name指針被分配一次內存,但是程序結束時該內存卻被釋放了兩次,會導致崩潰! ### 原因 ***** 這是由于編譯系統在我們沒有自己定義拷貝構造函數時,會在拷貝對象時調用默認拷貝構造函數,進行的是淺拷貝!即對**指針name拷貝后會出現兩個指針指向同一個內存空間。** ![](https://img-blog.csdn.net/20180201123405115?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2Fvc2hhbmdwYQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 所以,在對含有指針成員的對象進行拷貝時,必須要自己定義拷貝構造函數,使拷貝后的對象指針成員有自己的內存空間,即進行深拷貝,這樣就避免了內存泄漏發生。 ### 修改過后的例子 ``` #include <iostream> using namespace std; class Student { private: int num; char *name; public: Student(); ~Student(); Student(const Student &s);//拷貝構造函數,const防止對象被改變 }; Student::Student() { name = new char(20); cout << "Student" << endl; } Student::~Student() { cout << "~Student " << (int)name << endl; delete name; name = NULL; } Student::Student(const Student &s) { name = new char(20); memcpy(name, s.name, strlen(s.name)); cout << "copy Student" << endl; } int main() { {// 花括號讓s1和s2變成局部對象,方便測試 Student s1; Student s2(s1);// 復制對象 } system("pause"); return 0; } ``` 執行結果:調用一次構造函數,一次自定義拷貝構造函數,兩次析構函數。兩個對象的指針成員所指內存不同。 ?總結:淺拷貝只是對指針的拷貝,拷貝后兩個指針指向同一個內存空間,深拷貝不但對指針進行拷貝,而且對指針指向的內容進行拷貝,經深拷貝后的指針是指向兩個不同地址的指針。 ` ` 當對象中存在指針成員時,除了在復制對象時需要考慮自定義拷貝構造函數,還應該考慮以下兩種情形: 1.當函數的參數為對象時,實參傳遞給形參的實際上是實參的一個拷貝對象,系統自動通過拷貝構造函數實現; 2.當函數的返回值為一個對象時,該對象實際上是函數內對象的一個拷貝,用于返回函數調用處。 3.淺拷貝帶來問題的本質在于析構函數釋放多次堆內存,使用std::shared_ptr,可以完美解決這個問題。 關于std::shared_ptr的原理和實現可參考:[C++筆試題之smart pointer的實現](http://blog.csdn.net/caoshangpa/article/details/79221544) ` ` 一個完整的自定義類實現可參考:[C++筆試題之String類的實現](http://blog.csdn.net/caoshangpa/article/details/51530482)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看