• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            重載操作符 (c++primer 4e)

            Posted on 2010-03-15 16:40 rikisand 閱讀(1225) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++

            1.為啥要重載操作符:

            通過(guò)重載操作符,程序員可以針對(duì)“類”類型的操作數(shù)定義不同的操作符版本。良好的操作符定義可以使class類型的使用想內(nèi)置類型一樣直觀簡(jiǎn)潔,使用重定義的操作符而不是命名函數(shù)使得程序可以用表達(dá)式代替函數(shù)調(diào)用,使程序編寫和閱讀更容易~

            2.哪些不能重載

            ::     .*      .     ?:    這些不能重載

            3.需要注意的地方:

            重載必須有一個(gè)class類型的操作數(shù),短路求值失去,

            重載操作符和內(nèi)置操作符結(jié)合型相同,優(yōu)先級(jí)操作數(shù)個(gè)數(shù)均相同

            不要重載一些含有內(nèi)置定義的操作符 & , && || 這些

            ·賦值(=)下標(biāo)(【】)調(diào)用 (())和成員訪問(wèn)操作符必須定義為成員

            ·對(duì)稱的操作符一般定義為普通非成員函數(shù)

            ++ -- 一般設(shè)置為成員函數(shù) ,因?yàn)榭赡芨淖儗?duì)象狀態(tài)

            4.定義輸入輸出操作符

            io操作符只能重載為非成員函數(shù),否則做操作符只能是對(duì)象成員 用法變成了 object<<cin  不符合我們的習(xí)慣,經(jīng)常把他們?cè)O(shè)置成為友元,因?yàn)榭赡苡|及私有變量。

            輸入必須加入文件結(jié)束和輸入錯(cuò)誤的錯(cuò)誤處理

            istream&
            operator>>(istream& in, Sales_item& s)
            {
                 double price;
                 in >> s.isbn >> s.units_sold >> price;
                 // check that the inputs succeeded
                 if (in)
                    s.revenue = s.units_sold * price;
                 else
                    s = Sales_item(); // input failed: reset object to default state
                 return in;
            }

            如果輸入失敗,調(diào)用默認(rèn)構(gòu)造函數(shù)恢復(fù)對(duì)象狀態(tài)。

            5.算術(shù)運(yùn)算符和關(guān)系運(yùn)算符

            Sales_item& operator -=(const Sales_item& item){
                units_sold-=item.units_sold;
                revenue-=item.revenue;
                return *this;
            }
            Sales_item operator - (const Sales_item& lhs,const Sales_item& rhs){
                Sales_item res(lhs);
                res+=rhs;
                return res;
            }

             

            一般算術(shù)運(yùn)算符設(shè)置為非成員函數(shù),與內(nèi)置運(yùn)算符對(duì)應(yīng),選擇返回value 而不是引用。賦值運(yùn)算符重載為成員函數(shù),并用它來(lái)實(shí)現(xiàn)算術(shù)運(yùn)算符,這樣算術(shù)運(yùn)算符不用friend

            相等運(yùn)算符和不等運(yùn)算符一般成對(duì)出現(xiàn),且用一個(gè)實(shí)現(xiàn)另一個(gè)

            關(guān)系運(yùn)算符 == != > < 一般重載成非成員函數(shù)

            6.賦值操作符

            必須為成員函數(shù) (=號(hào))

            =和+=  -= 一般都需要返回左操作數(shù)的引用

            Sales_item& operator = (string is){
                isbn = is;
                return *this;
            }

            6.下標(biāo)操作符

            必須為類成員函數(shù)   返回引用使其可以在賦值操作的任意一邊

            一般定義一種const 返回常量引用 一種not const 引用

                 class Foo {
                 public:
                     int &operator[] (const size_t);
                     const int &operator[] (const size_t) const;
                     // other interface members
                 private:
                     vector<int> data;
                     // other member data and private utility functions
                  };

            int& Foo::operator[] (const size_t index)
                 {
                     return data[index];  // no range checking on index
                 }
                 const int& Foo::operator[] (const size_t index) const
                 {
                     return data[index];  // no range checking on index
                 }

            pari<string,string>& operator[] (const  vector< pair<string,string>* > ::size_type index){
                return *wait_list.at(index);//使用at判斷是否越界
            }

            6.成員訪問(wèn)操作符

            -> 一般要求重載為成員運(yùn)算符,*沒(méi)有要求 ,但成員比較常見~~~

            例子:auto-ptr~~~~

            ScreenPtr 的用戶將會(huì)傳遞一個(gè)指針,該指針指向動(dòng)態(tài)分配的 ScreenScreenPtr 類將擁有該指針,并安排在指向基礎(chǔ)對(duì)象的最后一個(gè) ScreenPtr 消失時(shí)刪除基礎(chǔ)對(duì)象。另外,不用為 ScreenPtr 類定義默認(rèn)構(gòu)造函數(shù)。因此,我們知道一個(gè) ScreenPtr 對(duì)象將總是指向一個(gè) Screen 對(duì)象,不會(huì)有未綁定的 ScreenPtr,這一點(diǎn)與內(nèi)置指針不同。應(yīng)用程序可以使用 ScreenPtr 對(duì)象而無(wú)須首先測(cè)試它是否指向一個(gè) Screen 對(duì)象。

                 // private class for use by ScreenPtr only 私有類,
                 class ScrPtr {
                     friend class ScreenPtr;
                     Screen *sp;
                     size_t use;
                     ScrPtr(Screen *p): sp(p), use(1) { }
                     ~ScrPtr() { delete sp; }
                 };
                    /*
                  * smart pointer: Users pass to a pointer to a dynamically allocated Screen, which
                  *                   is automatically destroyed when the last ScreenPtr goes away
                  */
                 class ScreenPtr {
                 public:
                     //  no default constructor: ScreenPtrs must be bound to an object
                     ScreenPtr(Screen *p): ptr(new ScrPtr(p)) { }
                     //  copy members and increment the use count
                     ScreenPtr(const ScreenPtr &orig):
                        ptr(orig.ptr) { ++ptr->use; }
                     ScreenPtr& operator=(const ScreenPtr&);
                     //  if use count goes to zero, delete the ScrPtr object
                     ~ScreenPtr() { if (--ptr->use == 0) delete ptr; }
                 private:
                     ScrPtr *ptr;    // points to use-counted ScrPtr class
                 };

            指針支持的基本操作有解引用操作和箭頭操作。我們的類可以這樣定義這些操作:

                 class ScreenPtr {
                 public:
                     // constructor and copy control members as before
                     Screen &operator*() { return *ptr->sp; }
                     Screen *operator->() { return ptr->sp; }
                     const Screen &operator*() const { return *ptr->sp; }
                     const Screen *operator->() const { return ptr->sp; }
                 private:
                     ScrPtr *ptr; // points to use-counted ScrPtr class
                 };

            解引用操作符是個(gè)一元操作符。在這個(gè)類中,解引用操作符定義為成員,因此沒(méi)有顯式形參,該操作符返回對(duì) ScreenPtr 所指向的 Screen 的引用。

            箭頭操作符不接受顯式形參。point->action();   等價(jià)于  (point->action)();

            可以這樣使用 ScreenPtr 對(duì)象訪問(wèn) Screen 對(duì)象的成員:

            ScreenPtr p(&myScreen);     // copies the underlying Screen
            p->display(cout);

            因?yàn)?p 是一個(gè) ScreenPtr 對(duì)象,p->display 的含義與對(duì) (p.operator->())->display 求值相同。對(duì) p.operator->() 求值將調(diào)用 ScreenPtr 類的 operator->,它返回指向 Screen 對(duì)象的指針,該指針用于獲取并運(yùn)行 ScreenPtr 所指對(duì)象的 display 成員。

            重載箭頭操作符必須返回指向類類型的指針,或者返回定義了自己的箭頭操作符的類類型對(duì)象。

            6.自增自減操作符

            一般重載為成員函數(shù),為了與內(nèi)置類型一致,前置操作符返回運(yùn)算結(jié)果引用,后置操作符返回運(yùn)算前的值,value not ref ,為了區(qū)分,后置操作符提供了一個(gè)實(shí)參0;

            // prefix: return reference to incremented/decremented object
                CheckedPtr& CheckedPtr::operator++()
                {
                    if (curr == end)
                        throw out_of_range
                              ("increment past the end of CheckedPtr");
                    ++curr;                // advance current state
                    return *this;
                }

            CheckedPtr CheckedPtr::operator++(int)
                 {

                     // no check needed here, the call to prefix increment will do the check
                     CheckedPtr ret(*this);        // save current value
                     ++*this;                      // advance one element, checking the increment 用前置實(shí)現(xiàn)它,不用判斷出界了
                     return ret;                   // return saved state
                 }

            顯式調(diào)用:

            CheckedPtr parr(ia, ia + size);        // iapoints to an array of ints
            parr.operator++(0);                    // call postfix operator++
            parr.operator++();                     // call prefix operator++

            7 調(diào)用操作符和函數(shù)對(duì)象

            struct absInt {
                   int operator() (int val) {
                       return val < 0 ? -val : val;
                   }
               };

             

            通過(guò)為類類型的對(duì)象提供一個(gè)實(shí)參表而使用調(diào)用操作符,所用的方式看起來(lái)像一個(gè)函數(shù)調(diào)用:

                 int i = -42;
                 absInt absObj;  // object that defines function call operator
                 unsigned int ui = absObj(i);     // calls absInt::operator(int)

            函數(shù)調(diào)用操作符必須聲明為成員函數(shù)。一個(gè)類可以定義函數(shù)調(diào)用操作符的多個(gè)版本,由形參的數(shù)目或類型加以區(qū)別。

            定義了調(diào)用操作符的類,其對(duì)象常稱為函數(shù)對(duì)象,即它們是行為類似函數(shù)的對(duì)象。

            函數(shù):

                 // determine whether a length of a given word is 6 or more
                 bool GT6(const string &s)
                 {
                     return s.size() >= 6;
                 }
            

            函數(shù)對(duì)象:

            // determine whether a length of a given word is longer than a stored bound
                 class GT_cls {
                 public:
                     GT_cls(size_t val = 0): bound(val) { }
                     bool operator()(const string &s)
                                        { return s.size() >= bound; }
                 private:
                     std::string::size_type bound;
                 };

            for (size_t i = 0; i != 11; ++i)
                 cout << count_if(words.begin(), words.end(), GT(i))
                      << " words " << i
                      << " characters or longer" << endl;

            函數(shù)對(duì)象的便捷性】

                     plus<int> intAdd;         // function object that can add two int values
                 negate<int> intNegate;   //  function object that can negate an int value
                 // uses intAdd::operator(int, int) to add 10 and 20
                 int sum = intAdd(10, 20);          // sum = 30
                 // uses intNegate::operator(int) to generate -10 as second parameter
                 // to intAdd::operator(int, int)
                 sum = intAdd(10, intNegate(10));    // sum = 0

            函數(shù)適配器:

            banding器,它通過(guò)將一個(gè)操作數(shù)綁定到給定值而將二元函數(shù)對(duì)象轉(zhuǎn)換為一元函數(shù)對(duì)象

            求反器是一種函數(shù)適配器,它將謂詞函數(shù)對(duì)象的真值求反。標(biāo)準(zhǔn)庫(kù)定義了兩個(gè)求反器:not1not2 分別求反一元二元對(duì)象

            8。實(shí)參匹配和轉(zhuǎn)換(俺來(lái)看重載操作符的原因啊,,,)

            轉(zhuǎn)換操作符是一種特殊的類成員函數(shù)。它定義將類類型值轉(zhuǎn)變?yōu)槠渌愋椭档霓D(zhuǎn)換。轉(zhuǎn)換操作符在類定義體內(nèi)聲明,在保留字 operator 之后跟著轉(zhuǎn)換的目標(biāo)類型:

            轉(zhuǎn)換函數(shù)采用如下通用形式:

                 operator type();
            

            轉(zhuǎn)換函數(shù)必須是成員函數(shù),不能指定返回類型,并且形參表必須為空。

            雖然轉(zhuǎn)換函數(shù)不能指定返回類型,但是每個(gè)轉(zhuǎn)換函數(shù)必須顯式返回一個(gè)指定類型的值。例如,operator int 返回一個(gè) int 值;如果定義 operator Sales_item,它將返回一個(gè) Sales_item 對(duì)象,諸如此類。

            轉(zhuǎn)換函數(shù)一般不應(yīng)該改變被轉(zhuǎn)換的對(duì)象。因此,轉(zhuǎn)換操作符通常應(yīng)定義為 const 成員。

            只要存在轉(zhuǎn)換,編譯器將在可以使用內(nèi)置轉(zhuǎn)換的地方自動(dòng)調(diào)用它

          1. In expressions:

            在表達(dá)式中:

                 SmallInt si;
                 double dval;
                 si >= dval          // si converted to int and then convert to double
          2. In conditions:

            在條件中:

                 if (si)                // si converted to int and then convert to bool
          3. When passing arguments to or returning values from a function:

            將實(shí)參傳給函數(shù)或從函數(shù)返回值:

                 int calc(int);
                 SmallInt si;
                 int i = calc(si);      // convert si to int and call calc
          4. As operands to overloaded operators:

            作為重載操作符的操作數(shù):

                 // convert si to int then call opeator<< on the int value
                 cout << si << endl;
          5. In an explicit cast:

            在顯式類型轉(zhuǎn)換中:

                 int ival;
                 SmallInt si = 3.541; //
                 instruct compiler to cast si to int
                 ival = static_cast<int>(si) + 3;
            

            類類型轉(zhuǎn)換之后不能再跟另一個(gè)類類型轉(zhuǎn)換。如果需要多個(gè)類類型轉(zhuǎn)換,則代碼將出錯(cuò)。(指的是不能連續(xù)兩個(gè)自定義的類型轉(zhuǎn)換,但是內(nèi)置類型轉(zhuǎn)換可以的)

          6. 還有一部分是實(shí)參匹配和轉(zhuǎn)換 ,沒(méi)時(shí)間了 以后再看~~~~

             

             

             

             

             

             

             

             

             

             

             

            国产精品成人99久久久久91gav| 久久WWW免费人成一看片| 色妞色综合久久夜夜| 久久久精品久久久久影院| 思思久久99热免费精品6| 久久99精品国产麻豆蜜芽| 国产高潮国产高潮久久久| 国产亚洲欧美精品久久久| 久久久久久久人妻无码中文字幕爆| 久久综合九色综合网站| 尹人香蕉久久99天天拍| 一本色道久久88精品综合 | 国产精品内射久久久久欢欢| 久久国产精品久久国产精品| 亚洲国产精久久久久久久| 久久综合久久综合久久| 久久本道久久综合伊人| 久久福利资源国产精品999| 久久精品国产亚洲AV不卡| 久久99国产乱子伦精品免费| 国产精品99久久99久久久| 国产精品伦理久久久久久| 久久综合亚洲色HEZYO国产| 久久国产劲爆AV内射—百度| 7777久久亚洲中文字幕| 久久99精品国产麻豆婷婷| 久久亚洲国产精品成人AV秋霞 | 久久久久国色AV免费观看| 亚洲国产小视频精品久久久三级 | 国产成人精品综合久久久| 久久精品国产亚洲精品2020| 国内精品久久久久久久涩爱| 亚洲成av人片不卡无码久久| 色综合久久中文字幕无码 | 精品久久久久久无码中文野结衣 | 蜜桃麻豆www久久国产精品| 日韩av无码久久精品免费| 久久精品国产亚洲7777| 久久青青草原亚洲av无码app| 久久免费国产精品| 国产午夜久久影院|