<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      深入理解c++構(gòu)造函數(shù), 復(fù)制構(gòu)造函數(shù)和賦值函數(shù)重載(operator=)

      以下代碼編譯及運行環(huán)境均為 Xcode 6.4, LLVM 6.1 with GNU++11 support, Mac OS X 10.10.2

      調(diào)用時機

      看例子

      //
      //  main.cpp
      //  test
      //
      //  Created by dabao on 15/9/30.
      //  Copyright (c) 2015年 Peking University. All rights reserved.
      //
      
      #include <iostream>
      
      class Base
      {
      public:
          Base()
          {
              std::cout<<"constructor"<<std::endl;
          }
          
          Base(Base &copy)
          {
              std::cout<<"copy constructor"<<std::endl;
          }
          
          const Base &operator=(Base &copy)
          {
              std::cout<<"operator="<<std::endl;
              return *this;
          }
      };
      
      int main(int argc, const char * argv[])
      {
      
          Base a;     // 1
          Base b = a;  // 2
          Base c(a);   // 3
          
          Base d;       // 4
          d = a;
          
          return 0;
      }
      

        輸出

      constructor
      copy constructor
      copy constructor
      constructor
      operator=
      

        1,2,3,4 是我們創(chuàng)建一個變量的最主要的方法(構(gòu)造序列本文不討論), 其中1,2,3是變量定義, 4是賦值. 因此很明顯:

      1. 定義會調(diào)用構(gòu)造函數(shù), 賦值會調(diào)用賦值函數(shù)(operator=)
      2. 復(fù)制構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù), 參數(shù)是一個變量實例而已
      3. 2和3等價, 3不會調(diào)用賦值函數(shù)(手誤) 2不會調(diào)用賦值函數(shù), 出現(xiàn)等號未必就是賦值
      4. 如果沒有重載以上函數(shù), 3和4效果會一樣, 但會少一次函數(shù)調(diào)用

       const來搗亂

      那么const又起到什么作用了呢?

      繼續(xù)來看例子

      //
      //  main.cpp
      //  test
      //
      //  Created by dabao on 15/9/30.
      //  Copyright (c) 2015年 Peking University. All rights reserved.
      //
      
      #include <iostream>
      
      class Base
      {
      public:
          Base()
          {
              std::cout<<"constructor"<<std::endl;
          }
          
          Base(Base &copy)
          {
              std::cout<<"copy constructor"<<std::endl;
          }
          
          const Base &operator=(Base &copy)
          {
              std::cout<<"operator="<<std::endl;
              return *this;
          }
      };
      
      Base creator()
      {
          Base ret;
          return ret;
      }
      
      int main(int argc, const char * argv[])
      {
      
          Base a = creator();    // 1
          
          Base b;
          b = creator();     // 2
          
          return 0;
      }
      

        上述代碼都會編譯出錯, 原因是 "No matching constructor". 看代碼不難發(fā)現(xiàn)原因, creator函數(shù)返回的是Base類型, 在c++11里面, 這個稱為右值(rvalue), 但是我們的復(fù)制構(gòu)造函數(shù)和賦值函數(shù)的參數(shù)類型都是非const引用類型, 而右值是不允許做這種類型參數(shù)的, 所以就編譯出錯了. 解決方案有兩個:

      1. 使用const引用類型
      2. 使用右值類型

      如下所示

          Base(const Base &copy)
          {
              std::cout<<"copy constructor"<<std::endl;
          }
          
          const Base &operator=(Base &&copy)
          {
              std::cout<<"operator="<<std::endl;
              return *this;
          }
      

        其中, const引用類型是最通用的作法, 它可以兼容左值和右值, 也兼容古老的編譯器, 右值類型則是c++11引進的新特性(使用&&表明), 可以針對左值和右值選擇不同的實現(xiàn), 比如使用std::move替代operator=, 從而減少內(nèi)存的申請. 因此, 如果沒有特殊需要, 使用const引用類型作為復(fù)制構(gòu)造函數(shù)與賦值函數(shù)的參數(shù)類型.

       

      至此, 構(gòu)造函數(shù)的坑基本說完了, 因為不牽扯到返回值和函數(shù)類型的問題, 但是賦值函數(shù)(operator=)還有更多的坑來理一理.

      const繼續(xù)攪局

      在一個類的成員函數(shù)中, const可以出現(xiàn)三個地方: 返回值, 參數(shù), 函數(shù).

      const A& operator=(const A& a) const
      

      因此一個函數(shù)可以有8個變種, 但是c++不允許參數(shù)類型相同,返回值類型不同的重載, 因此一個函數(shù)最多有4種實現(xiàn). 

      我們先考慮返回const類型的情況

      //
      //  main.cpp
      //  test
      //
      //  Created by dabao on 15/9/30.
      //  Copyright (c) 2015年 Peking University. All rights reserved.
      //
      
      #include <iostream>
      
      class A
      {
      public:
          const A& operator=(const A& a) const
          {
              std::cout<<"const A& operator=(const A& a) const ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          const A& operator=(const A& a)
          {
              std::cout<<"const A& operator=(const A& a) ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          const A& operator=(A& a) const
          {
              std::cout<<"const A& operator=(A& a) const ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          const A& operator=(A& a)
          {
              std::cout<<"const A& operator=(A& a) ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          std::string x;
          
          A() : x(""){}
          A(std::string x_) : x(x_) {}
      };
      
      int main(int argc, const char * argv[])
      {
      
          A a("a"), b("b");
          const A c("const c"),d("const d");
          
          c = d;
          c = b;
          a = d;
          a = b;
          
          return 0;
      }
      

       輸出結(jié)果

      const A& operator=(const A& a) const [const d > const c]
      const A& operator=(A& a) const [b > const c]
      const A& operator=(const A& a) [const d > a]
      const A& operator=(A& a) [b > a]
      

      結(jié)果很明顯, 被賦值變量決定函數(shù), 賦值變量決定參數(shù), a=b 等價于 a.operator(b), 這里沒什么問題.

      但是, 有一個很奇怪的地方, a=d 這一句, a是非const的, 調(diào)用了 const A& operator=(const A& a) [const d > a], 返回值是個const類型, 這怎么可以呢? 返回值的const是什么意思呢? 這是非常有迷惑性的. 這個問題的關(guān)鍵點在于:

      a是這個函數(shù)的一部分, 并不是返回值的承接者. 因此 a=d 實際上是等價于 const A& ret = a.operator=(d), 也就是說, operator=的返回值類型和被賦值的變量是沒有任何關(guān)系的! 

      加入以下代碼

          const A &m = (a = d);  // 1
          A &n = (a = d);      // 2
      

      2會編譯錯誤, 原因就在于把 const A& 綁定給 A&, 這肯定是錯誤的. 因此再重復(fù)一遍, operator=的返回值和被賦值變量沒有任何關(guān)系.

      那么返回值有什么意義呢? 這就和iostream類似了, 是為了進行串聯(lián)賦值, 亦即 a=b=c

      來看最后的例子

      //
      //  main.cpp
      //  test
      //
      //  Created by dabao on 15/9/30.
      //  Copyright (c) 2015年 Peking University. All rights reserved.
      //
      
      #include <iostream>
      
      class A
      {
      public:
          const A& operator=(const A& a) const
          {
              std::cout<<"const A& operator=(const A& a) const ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          const A& operator=(const A& a)
          {
              std::cout<<"const A& operator=(const A& a) ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          const A& operator=(A& a) const
          {
              std::cout<<"const A& operator=(A& a) const ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          const A& operator=(A& a)
          {
              std::cout<<"const A& operator=(A& a) ["<<a.x<<" > "<<x<<"]"<<std::endl;
              return *this;
          }
          
          std::string x;
          
          A() : x(""){}
          A(std::string x_) : x(x_) {}
      };
      
      int main(int argc, const char * argv[])
      {
      
          A a("a"), b("b");
          
          const A c("const c"),d("const d");
          
          (a = b) = c;    // 1
          
          (a = c) = b;    // 2
          
          a = b = c;     // 3
          
          return 0;
      }
      

      輸出

      const A& operator=(A& a) [b > a]
      const A& operator=(const A& a) const [const c > a]
      const A& operator=(const A& a) [const c > a]
      const A& operator=(A& a) const [b > a]
      const A& operator=(const A& a) [const c > b]
      const A& operator=(const A& a) [b > a]
      

        

      可以得出如下結(jié)論:

      1. 1和3比較可以發(fā)現(xiàn), 賦值的順序是從右往左執(zhí)行的
      2. 返回值是const類型, 那么再被賦值就會調(diào)用const函數(shù)了

      總結(jié)

      1. 復(fù)制構(gòu)造函數(shù)和賦值函數(shù)出現(xiàn)在兩種不同的場景里, 不是出現(xiàn)等號就會調(diào)用賦值函數(shù)
      2. 賦值函數(shù)的返回值和被賦值變量是完全獨立的

       

      posted on 2015-09-30 17:25  大寶pku  閱讀(7580)  評論(3)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 无码国模国产在线观看免费| 午夜精品区| 精品免费看国产一区二区| 国产精品美女一区二区三| 国产永久免费高清在线观看| 一本加勒比hezyo无码专区 | 无码人妻精品丰满熟妇区 | 欧美成人aaa片一区国产精品| 丰满少妇又爽又紧又丰满在线观看| 商丘市| 九九热在线精品免费视频| 国产综合久久99久久| 欧美成人片在线观看| 极品少妇的粉嫩小泬看片| 美欧日韩一区二区三区视频| 囯产精品久久久久久久久久妞妞| 日韩在线视频线观看一区| 开心五月激情五月俺亚洲| 蜜桃av一区二区高潮久久精品| 成人午夜在线观看刺激| 国产免费午夜福利在线播放| 免费看久久妇女高潮a| 亚洲a∨国产av综合av| 国产又色又爽又黄的网站免费| 9色国产深夜内射| 分宜县| 国产精品综合一区二区三区 | 亚洲国产成人久久综合野外 | 国产午夜福利短视频| 北条麻妃42部无码电影| 大地资源免费视频观看| 巨胸喷奶水视频www免费网站| 国产成人人综合亚洲欧美丁香花| 午夜福利在线永久视频| 麻豆成人精品国产免费| 国产极品美女高潮无套| 精品亚洲欧美无人区乱码| 久久人人爽人人爽人人av| 午夜福利偷拍国语对白| 国产精品女在线观看| 91中文字幕在线一区|