<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、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 一.對象的賦值 1. **實質操作** 把對象的每個數據成員的值賦值給運算符左邊的同類型對象。 2. **操作對象** 數據成員。 >[warning]不會復制成員函數,因為相同類型的對象共用成員函數的代碼。 ## 二.拷貝構造函數 ### 1.作用 + 指導編譯器為對象分配空間 + 完成對象的初始化操作 ### 2.特點 + **無名函數** 因為類型名不能作為函數名。 + **不可指定返回類型** 不能指定任何返回類型,即使void也不行。 + **支持成員初始化列表** ### 3.定義和聲明 類似于構造函數,但第一個參數必須為對象的引用。 為支持常對象,一般第一個參數設置為常引用。 ```c++ //一般舊對象那里會加上 const ,防止原對象被修改。 //如需多個參數,后面的參數需要加默認值 類名(類名& 舊對象) { //code here } ``` ### 4.調用時機 用 **同類型的對象** 拷貝初始化正在被創建的 **同類型的對象** 時。即: + 使用一個已存在的同類型對象初始化另一個正在被創建同類型對象。 + 從函數傳遞一個對象(而不是對象的引用)。 + 從函數返回一個對象(而不是對象的引用)。 對于派生類的拷貝構造函數,若類類型成員沒有出現在成員初始化列表,則類類型成員執行 **無參構造函數** 。 >[warning] \[17+\]\[17-的編譯器可能支持\] 若使用函數返回的對象創建一個新對象(或沒有變量接受返回值),則有可能發生復制消除。 ```c++ #include <iostream> using namespace std; class Complex { private: double real_; double imaginary_; public: Complex() : real_(0), imaginary_(0) { cout << "已調用無參構造函數" << endl; } Complex(double real) : real_(real), imaginary_(0) { cout << "已調用普通構造函數" << endl; } Complex(double real, double imaginary) : real_(real), imaginary_(imaginary) { cout << "已調用普通構造函數" << endl; } Complex(const Complex &old) { this->real_ = old.real_; this->imaginary_ = old.imaginary_; cout << "已調用拷貝構造函數" << endl; } double get_real() { return this->real_; } double get_imaginary() { return this->imaginary_; } Complex &set_real(double new_val) { this->real_ = new_val; return *this; } Complex &set_imaginary(double new_val) { this->imaginary_ = new_val; return *this; } }; void pass_a_complex(Complex c) //拷貝初始化,調用拷貝構造函數 { } Complex return_a_complex() { return Complex(10, 10); //直接初始化,普通構造函數 } int main() { Complex a; //默認初始化,調用無參構造函數 Complex b(10, 10); //直接初始化,調用普通構造函數 Complex c = 10; //拷貝初始化,調用普通構造函數 Complex d = c; //拷貝初始化,調用拷貝構造函數 Complex e(a); //拷貝初始化,調用拷貝構造函數 Complex f = return_a_complex(); //拷貝初始化,可能調用兩次拷貝構造函數,也可能不調用任何構造函數(復制消除) pass_a_complex(b); //向函數傳遞對象,調用拷貝構造函數 return_a_complex(); //從函數返回對象,可能會調用拷貝構造函數 return 0; } ``` >[test-gpp] > 已調用無參構造函數 > 已調用普通構造函數 > 已調用普通構造函數 > 已調用拷貝構造函數 > 已調用拷貝構造函數 > 已調用普通構造函數 > 已調用拷貝構造函數 > 已調用普通構造函數 >[test-vc] > 已調用無參構造函數 > 已調用普通構造函數 > 已調用普通構造函數 > 已調用拷貝構造函數 > 已調用拷貝構造函數 > 已調用普通構造函數 > 已調用拷貝構造函數 > 已調用拷貝構造函數 > 已調用拷貝構造函數 > 已調用普通構造函數 > 已調用拷貝構造函數 ### 5.默認拷貝構造函數 如用戶未定義拷貝構造函數,則編譯器會產生一個默認的拷貝構造函數。在默認的拷貝構造函數中,每個成員直接逐個復制。類類型成員調用 **拷貝構造函數** 。 >當類滿足下列條件時,編譯器 **不會** 自動創建默認的拷貝構造函數: > >+ 有用戶定義的拷貝構造函數 >當類滿足下列條件時,編譯器會將拷貝構造函數定義為棄置的(`delete`)(C++11之前,這些情況下編譯器不會自動創建默認的拷貝構造函數): >+ 非靜態類類型數據成員或基類沒有拷貝構造函數,或拷貝構造函數不能訪問(例如將拷貝構造函數設置為私有)。 >+ 非靜態類類型數據成員或基類沒有析構函數,或析構函數不能訪問(例如將析構函數設置為私有)。 >+ [11+]有用戶定義的移動構造函數和移動賦值操作。 ## 三.拷貝賦值操作 ### 1.作用 + 完成對象之間的賦值 ### 2.特點 1. **有名** 2. **有參** 3. **有返回值** ### 3.定義與聲明 + **重載賦值運算符** 參數為對象的引用,返回值為自身的引用。 + **只能作為成員函數** + **不允許默認參數** ### 4.調用時機 + 對象賦值(不是對象的初始化) ### 5.默認拷貝賦值操作 >當類滿足下列條件時,編譯器 **不會** 自動創建默認的拷貝賦值操作: > >+ 有用戶定義的拷貝賦值操作 >當類滿足下列條件時,編譯器會將拷貝構造函數定義為棄置的(`delete`)(C++11之前,這些情況下編譯器不會自動創建默認的拷貝構造函數): >+ 非靜態類類型數據成員或基類沒有拷貝構造函數,或拷貝構造函數不能訪問(例如將拷貝賦值操作設置為私有)。 >+ 非靜態類類型數據成員或基類沒有析構函數,或析構函數不能訪問(例如將析構函數設置為私有)。 >+ [11+]有用戶定義的移動構造函數和移動賦值操作。 >+ 某個非靜態數據成員是引用類型。 >+ 某個非靜態數據成員是常量或常量數組。 ## 四.合成的拷貝函數與動態內存分配 - 如果數據成員的值是一個動態分配的地址,那么在對象復制的時候,程序僅僅把地址復制過來,而不會重新創建新的空間。這樣,兩個對象的某個數據成員會指向同一片內存區域。 **在對象析構的時候,會重復刪除同一片動態內存空間** 。 + 解決問題的辦法就是自定義拷貝函數。兩種設計方法: + **深拷貝法** 復制對象的時候重新創建空間。 + **優點** 簡單,每個對象擁有獨立的空間。 + **缺點** 內存開銷較大,速度慢。(時間復雜度和空間復雜度高,為線性級) + 在C++中,對象的復制一般使用 **深拷貝法** 。 + **淺拷貝法** 設置一個數據成員 `power` ,對象復制的時候,將運算符右邊的對象的 `power` 設置為 `false`。析構的時候,若 `power` 為 `false` 則不刪除動態空間。 + **優點** 速度快,內存開銷小。(時間復雜度和空間復雜度低,為常數級) + **缺點** 不同對象之間占用同一片內存區域,修改那一塊區域的值,所有對象獲得的數據都會改變。 + 其他的語言如 `python` 和 `JavaScript` 復制一個容器,默認使用淺拷貝法。
                  <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>

                              哎呀哎呀视频在线观看