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

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

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

      Effective C++ 類與函數(shù)設(shè)計(jì)和申明

      Effective C++ 類與函數(shù)的設(shè)計(jì)和申明

      在看《Effective C++》這本書的過程中,我無數(shù)次的發(fā)出感嘆,這他媽寫得太好了,句句一針見血,直接說到點(diǎn)上。所以決定把這本書的內(nèi)容加上自己的理解寫成5篇博客,我覺得不管你是否理解這些條款,都值得你先記下來。下面的索引對應(yīng)的是書中的章節(jié)。

      18:努力讓接口完美且最小化

      19:區(qū)分member functions,non-member functions和friend functions三者

      20:避免將data member放在公開接口中

      21:盡量使用const

      22:盡量使用 pass-by-refernece,少用pass-by-value

       

      18:努力讓接口完美且最小化

      為了客戶端的方便調(diào)用,接口中可能會定義很多方法,而其中可能右很多方法是多余或是重復(fù)的,這樣會導(dǎo)致接口中方法太多,讓用戶迷失在一堆的方法中,而且大型接口不易維護(hù),長長的class定義導(dǎo)致頭文件很長,會增大編譯的時(shí)間。但是也不必太過吝嗇方法的個(gè)數(shù),如果加入一個(gè)member function會是class更好用,會是增加一個(gè)member function能減少客戶端的錯(cuò)誤,那都是這些方法都是成為接口一份子的理由。

      19:區(qū)分member functions,non-member functions和friend functions三者

      member function可以是虛函數(shù)而non-member function不可以,如果一個(gè)函數(shù)必須是動態(tài)綁定的那么他就必須是虛函數(shù),就必須是memberfunction,虛函數(shù)能實(shí)現(xiàn)動態(tài)綁定是因?yàn)樽宇惪梢愿鶕?jù)自己的需要重寫父類的虛方法實(shí)現(xiàn)動態(tài)綁定,而non-member function不可能被重寫。Friend function是獨(dú)立于class的,他只是可以訪問class的私有成員,如果一個(gè)方法不需要訪問一個(gè)class的私有成員,就不應(yīng)該讓這個(gè)方法稱為這個(gè)類的friend function。

      class Rational
      {
          public:
              Rational(int numerator=0,int denominator=1);
              int numerator()const;
              int denominator() const;
              const Rational operator*(const Rational& rhs)const;
          private:
              ...
      };

       

      上面這個(gè)類表示一個(gè)分?jǐn)?shù),分?jǐn)?shù)的加減乘除的方法都沒有提供,那我們該以什么樣的方式實(shí)現(xiàn)這些操作呢,是member function還是non-member function還是friend function呢?

      第一直覺就是這些操作是屬于Rational的應(yīng)該是member function,那么我們就新增一個(gè)關(guān)于乘法的public member function,就是下面這個(gè)樣子:

      const Rational operator*(const Rational& rhs)const;

      簡單的介紹為什么是這個(gè)樣子。先解釋3個(gè)const,第一個(gè)const表示方法的返回為const,就是禁止我們對一個(gè)乘法賦值,如禁止a*b=3;第二個(gè)const表示在這個(gè)方法中不能修改rhs中任何成員的值,第三個(gè)const表示這個(gè)方法是const方法,在這個(gè)方法中不能修改調(diào)用這個(gè)方法的對象的數(shù)據(jù)成員。Const還有其他很多作用將會在下一個(gè)條款中介紹。

      返回值為什么是by value?首先我們必須用一個(gè)變量來存乘法的結(jié)果值,我們不能在方法中構(gòu)造一個(gè)局部變量,然后返回他的引用,因?yàn)檫@個(gè)方法執(zhí)行完后,局部變量會被自動回收。

      參數(shù)為什么為引用類型?一句話盡量用by reference代替by value,條款22專門講述這個(gè)問題。這個(gè)返回值返回使用by value是沒有其他辦法了,你必須用一個(gè)變量來存放結(jié)果值。有了這個(gè)方法我們就可以進(jìn)行乘法操作了。

      Rational oneHalf(1,2),twoFive(2,5);

      Rational result=oneHalf*twoFive;//沒有問題

      Result=oneHalf*3;//沒有問題,在類型不匹配的時(shí)候編譯器會一直尋找隱式類型轉(zhuǎn)換的方法,直到找不到報(bào)錯(cuò),由于構(gòu)造函數(shù)的兩個(gè)參數(shù)都有默認(rèn)值,所以可以發(fā)生隱式類型轉(zhuǎn)換,3相當(dāng)于Rational(3,1),于是不會出現(xiàn)任何問題。

      乘法的交換律告訴我們:a*b=b*a;于是我想oneHalf*3可以寫成3*oneHalf,但是對不起不行,

      3*oneHalf相當(dāng)于3.operator(oneHalf),在這個(gè)3是操作對象,不會發(fā)生任何類型轉(zhuǎn)換,而oneHalf是參數(shù),于是編譯器尋找將Rational轉(zhuǎn)換成int(假設(shè)3為int類型)的方法,當(dāng)然是沒有啦。為了實(shí)現(xiàn)Rational和int類型的任意操作用member function是不可能啦,于是用non-member function,于是寫下乘法的方法如下:

      const Rational operator*(const Rational& lhs,const Rational& rhs)
      {
          return Rational(lhs.numerator()*rhs.numerator(),lhs.denominator()*rhs. denominator());
      }

       

      Non-member function當(dāng)然不需要用cosnt修飾,將乘法結(jié)果存在一個(gè)匿名變量中,如果編譯有優(yōu)化的話,這個(gè)結(jié)果將直接存在接收這個(gè)方法的變量中。有了這個(gè)方法,3*oneHalf就沒有任何問題了,現(xiàn)在3被隱式轉(zhuǎn)換成Rational(3,1)了,不會出現(xiàn)任何問題,如果你不想出現(xiàn)隱式類型轉(zhuǎn)換,就在構(gòu)造函數(shù)的前面加上explicit。最后要考慮的是是否需要將這個(gè)方法稱為Rational的friend function,當(dāng)然是不需要,因?yàn)樽屗Q為friend function沒有任何幫助,多一個(gè)沒有任何幫助的朋友有這個(gè)必要嗎?

       

      20:避免將data member放在公開接口中

      將data member設(shè)為private,然后用member function實(shí)現(xiàn)讀寫操作,對于用過面向?qū)ο笳Z言的朋友都知道,就不廢話了。如果這些方法只是返回data member的話,可以讓這些方法稱為inline,就可以節(jié)省方法調(diào)用帶來的性能損失。

       

      21:盡量使用const

      關(guān)于這一條上面也提到一些。

      Const修飾方法的返回值表示不可以直接對這個(gè)方法進(jìn)行賦值;

      Const修飾方法表示在這個(gè)方法中不能修改data member;

      Const修飾參數(shù)表示這個(gè)參數(shù)在這個(gè)方法中不能修改;

      常量性的不同也可以實(shí)現(xiàn)方法的重載,常量對象只能調(diào)用對應(yīng)的常量方法。非常量對象可以調(diào)用常量方法。

       

      22:盡量使用 pass-by-refernece,少用pass-by-value

      先看一個(gè)類,然后看兩個(gè)方法的對比,其他的廢話就多說了,因?yàn)镃#引用類型默認(rèn)的是pass-by-reference,而C++任何類型默認(rèn)的都是pass-by-value。

       

      class DataItem
      {
          public:
              DataItem()
              {
                  cout<<"    constructor DataItem"<<endl;
              }
              ~DataItem()
              {
                  cout<<"    ~destructor DataItem"<<endl;
              }
      
              DataItem(const DataItem& item)
              {
                  cout<<"    constructor DataItem"<<endl;
                  value=item.value;
                  text=item.text;
                  //*this=item;//這句的作用等同于上面兩句,但是它會調(diào)用operator= ,就多了一次方法調(diào)用 
              }
              
              const DataItem&  operator=(const DataItem&  item)
              {
                  cout<<"    operator= DataItem"<<endl;
                  text=item.text;
                  value=item.value;
      
                  return *this;
              }
      
              DataItem* operator&()
              {
                  return this;
              }
      
              const DataItem* operator&()const
              {
                  return this;
              }
       
              int GetValue()
              {
                  return value;
              }
      
              void SetValue(int val)
              {
                  value=val;
              }
      
              string& GetText()
              {
                  return *text;
              }
      
              void SetText(string* txt)
              {
                  text=txt;
              }
      
          private : 
              int value;
              string* text;
      };

      兩個(gè)對比方法及測試代碼:

      DataItem getDataItemByValue(DataItem item)
      {
          return item;
      }
      
      const DataItem& getDataItemByReference(const DataItem& item)
      {
          return item;
      }
      void TestDataItem()
      { 
           DataItem item; 
           cout<<"getDataItemByValue start:"<<endl;
           getDataItemByValue(item);
           cout<<"getDataItemByValue end"<<endl;
           cout<<endl;
           cout<<"getDataItemByReference start:"<<endl;
           getDataItemByReference(item);
           cout<<"getDataItemByReference end"<<endl; 
      }


      結(jié)果截圖:

      從結(jié)果中我們看到pass-by-value多調(diào)用兩次構(gòu)造函數(shù),兩次析構(gòu)函數(shù),還有對象的數(shù)據(jù)成員的構(gòu)造和析構(gòu),損失的確是很慘重。

      廢話真的不想多少了,寫這種博客真他媽累,有不想寫的念頭了,還是把時(shí)間放在實(shí)戰(zhàn)練習(xí)中吧。

      Effective c++這個(gè)系列暫時(shí)暫停。

       

      Effective C++系列:

            Effective C++構(gòu)造函數(shù)析構(gòu)函數(shù)Assignment運(yùn)算符

        Effective C++ 類與函數(shù)的設(shè)計(jì)和申明

         Effective C++面向?qū)ο笈c繼承

      作者:陳太漢

      博客:http://www.rzrgm.cn/hlxs/

       

      posted @ 2012-07-22 11:17  古文觀芷  閱讀(3325)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 999精品全免费观看视频| 亚洲中文字幕有综合久久| 亚洲性线免费观看视频成熟| 男女激情一区二区三区| 国产成人综合色在线观看网站| 小污女小欲女导航| 无码精品一区二区免费AV| 无码专区视频精品老司机| 国产精品疯狂输出jk草莓视频| 办公室强奷漂亮少妇视频| 69人妻精品中文字幕| 国色天香中文字幕在线视频| 在线精品视频一区二区三四| 象山县| 久热久热中文字幕综合激情| 99中文字幕国产精品| 又爽又黄无遮挡高潮视频网站| 欧美性猛交xxxx免费看| 亚洲国产精品日韩av专区| 国产日韩精品视频无码| 黄色免费在线网址| 国产精品无遮挡又爽又黄| 国产精品毛片一区二区| 最新国产精品好看的精品| 国产成人久久综合第一区| 2021国产在线视频| 天堂亚洲免费视频| 亚洲一区二区美女av| 亚洲国产美女精品久久久| 亚洲欧洲色图片网站| 亚洲国产成人综合自在线| 亚洲性图日本一区二区三区 | 国产日韩av免费无码一区二区三区| 国产又黄又爽又不遮挡视频| 亚洲国产中文在线有精品| 蜜芽久久人人超碰爱香蕉| 国产一卡2卡三卡4卡免费网站| 日韩欧美人妻一区二区三区| 白嫩人妻精品一二三四区| 福利视频一区二区在线| 亚洲成av人片天堂网老年人|