<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # [12] 賦值算符 ## FAQs in section [12]: * [12.1] 什么是“自賦值”? * [12.2] 為什么應該當心“自賦值”? * [12.3] 好,好;我會處理自賦值的。但如何做呢? ## 12.1 什么是“自賦值”? 自賦值就是將對象賦值給本身。例如, ``` ?#include?"Fred.hpp"????//?聲明 Fred 類? ?void?userCode(Fred&?x) ?{ ???x?=?x;???//?自賦值 ?} ``` 很明顯,以上代碼進行了顯式的自賦值。但既然多個指針或引用可以指向相同對象(別名),那么進行了自賦值而自己卻不知道的情況也是可能的: ``` ?#include?"Fred.hpp"????//?聲明 Fred 類 ?void?userCode(Fred&?x,?Fred&?y) ?{ ???x?=?y;???//?如果&x?==?&y就可能是自賦值 ?} ?int?main() ?{ ???Fred?z; ???userCode(z,?z); ?} ``` ## 12.2 為什么應該當心“自賦值”? 如果不注意自賦值,將會使你的用戶遭受非常微妙的并且一般來說非常嚴重的bug。例如,如下的類在自賦值的情況下將導致災難: ``` ?class?Wilma?{?}; ?class?Fred?{ ?public: ???Fred()????????????????:?p_(new?Wilma())??????{?} ???Fred(const?Fred&?f)???:?p_(new?Wilma(*f.p_))?{?} ??~Fred()????????????????{?delete?p_;?} ???Fred&?operator=?(const?Fred&?f) ?????{ ???????//?差勁的代碼:沒有處理自賦值! ???????delete?p_;????????????????//?Line?#1 ???????p_?=?new?Wilma(*f.p_);????//?Line?#2 ???????return?*this; ?????} ?private: ???Wilma*?p_; ?}; ``` 如果有人將 `Fred` 對象賦給其本身,由于`*this`和 `f` 是同一個對象,line #1同時刪除了`this->p_`和`f.p_`。而 line #2使用了已經不存在的對象`*f.p_`,這樣很可能導致嚴重的災難。 作為 `Fred`類的作者,你最起碼有責任確信在`Fred`對象上自賦值是無害的。不要假設用戶不會在對象上這樣做。如果對象由于自賦值而崩潰,那是_你的_過失。 > 另外:上述的`Fred::operator=?(const?Fred&)`還有第二個問題:如果在執行`new?Wilma(*f.p_)`時,拋出了異常或者`Wilma`的拷貝構造函數中的異常), `this->p_`將成為懸空指針——它所指向的內存不再是可用的。這可以通過在刪除就對象前創建對象來解決。 ## 12.3 好,好;我會處理自賦值的。但如何做呢? 在你創建類的每時每刻,都應該當心自賦值。這并不意味著需要為你所有的類都增加額外的代碼:只要對象優雅地處理自賦值,而不管是否必須增加額外的代碼。 如果不需要為賦值算符增加額外代碼,這里有一個簡單而有效的技巧: ``` ?Fred&?Fred::operator=?(const?Fred&?f) ?{ ???if?(this?==?&f)?return?*this;???//?優雅地處理自賦值 //?此處寫正常賦值的代碼... ???return?*this; ?} ``` 顯式的測試并不總是必要的。例如,如果修正前一個 FAQ中的賦值算符使之處理`new`拋出的異常和/或`Wilma`類的拷貝構造函數拋出的異常,可能會寫出如下的代碼。注意這段代碼有(令人高興的)自動處理自賦值的附帶效果: ``` ?Fred&?Fred::operator=?(const?Fred&?f) ?{ ???//?這段代碼優雅地(但隱含的)處理自賦值 ???Wilma*?tmp?=?new?Wilma(*f.p_);???//?如果異常在此處被拋出也沒有問題 ???delete?p_; ???p_?=?tmp; ???return?*this; ?} ``` 在象這個例子的情況下(自賦值是無害的但是低效),一些程序員想通過增加另外的不必要的測試,如“`if?(this?==?&f)?return?*this;`”來改善自賦值時的效率。通常來說,使自賦值情況更高效而使得非自賦值情況更低效的折衷是錯誤的。例如,為`Fred`類的賦值算符增加如上的`if`測試會使得非自賦值情況更低效(一個額外的(而且不必要的)條件分支)。如果自賦值實際上一千次才發生一次,那么 `if`將浪費99.9%的時間周期。
                  <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>

                              哎呀哎呀视频在线观看