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

            隨感而發

            雜七雜八

            統計

            留言簿(13)

            閱讀排行榜

            評論排行榜

            c++操作符重載

            今天我學習的是C++操作符重載。C++的操作符重載給C++帶來很大的方便和靈活性。可以重載里面大部分操作符。這樣在調用的時候就會相對的自然和簡單。廢話少說,直接奉上源代碼(有部分相關的資料的注釋都已經寫在源代碼上了):
              1 //一位是學習代碼,所以寫的相對叫亂,如果是其他的就應該規范些
              2 #include<stdio.h>
              3 #include <stdlib.h>
              4 
              5 //總結:重載操作符可以寫成成員函數和友員函數。成員函數是類內部的
              6 //函數,而友員函數是外部的函數,例如全局函數,甚至其他類里面的函數,我的習慣是
              7 //寫成成員函數,因為我覺得這樣感覺要好一點,而且在成員函數中參數還可以少一個。
              8 //哈哈,不過問題就是他不能重載左二元操作符(符號在他的左邊),也就是操作符是在他的左邊,所以在
              9 //重載一個整數和這個類相加的情況就只能寫友員函數了。
             10 //重載操作符的參數個數一定要跟默認參數個數的一樣,除了()這樣的可以自己定義以外,
             11 //例如operator+();這是錯誤的,還有operator(int a, int b,int c);這也是錯誤的
             12 //我下面之所以只有一個,是因為他是成員函數。自己已經包括在里面了,而友員就必須兩個都寫。
             13 //重載的返回類型沒有規定,C++也不是用返回來判斷是否重載的,
             14 //他是根據函數名和參數列表來判斷的。成員函數加const也是重載的一種,但是如果其他都一樣只有
             15 //返回類型不一致,就認為是錯誤的重載。例如:
             16 //int operator+(int nAdd) const;和 
             17 //CBaseOperator operator+(const CBaseOperator& cAdd) const;就會認為是錯誤的重載
             18 //而int operator+(int nAdd) const;和int operator+(int nAdd);就是正確的,他們是兩個不同的函數
             19 //在調用上,在未指明為const的類調用時,使用的是非const的函數。如果沒有非const的函數,
             20 //他才會調用const的函數。而如果const的類去調用非const的函數,會直接報錯。所以
             21 //在寫代碼時,可以考慮是不是可能會修改成員,如果希望是不修改的,那么請用const,這樣強制性的
             22 //會提高你的編碼能力的。(扯遠了,呵呵。)
             23 //都說友員是一個強大的東東,可以訪問內部的private函數和變量,但是,如果把拷貝構造函數和
             24 //=重載為私有的話,他是不能訪問的。。哈哈。設計語言的人真厲害。。
             25 
             26 //百度百科找的資料:
             27 //什么時候定義類成員操作符重載,什么時候定義非類成員操作符重載?
             28 //答:(1)如果一個重載操作符是類成員,那么只有當跟它一起使用的左操作數是該類對象時,
             29 //它才會被調用,如果該操作符的左操作數必須是其他類型,那么重載操作符必須是非類成員操作符重載。
             30 //(2)C++要求,賦值(=),下標([ ]),調用(())和成員訪問箭頭(->)操作符必須被指定為類成員操作符,否則錯誤。
             31 
             32 //http://www.examda.com/ncre2/cpp/fudao/20080312/092830274-2.html 網站的資料
             33 //不能重載的操作符號:
             34 //. .* :: ?: new delete sizeof typeid static_cast dynamic_cast const_cast reintERPret_cast
             35 //可以重載的操作符:
             36 //operator new operator delete operator new[] operator delete[] 
             37 // + - * / % ^ & | ~ ! = < > += -= *= /= %=  ^= &= |= << >> >>= <<= == !=
             38 // <= >= && || ++ -- , ->* -> () []
             39 //貌似這里可以重載new
             40 
             41 //重載簡單的+-*/%等
             42 class CBaseOperator
             43 {
             44 
             45 public:
             46     int nData;        //測試的變量
             47 
             48 public:
             49     CBaseOperator(int nData = 0):nData(nData)
             50     {
             51         nData++;
             52         --nData;
             53     }
             54 
             55     
             56     CBaseOperator(const CBaseOperator& cBO)
             57     {
             58         nData = cBO.nData;
             59     }
             60     //重載=操作符,一般=操作符和拷貝構造函數是成對出現的。
             61     const CBaseOperator& operator=(const CBaseOperator& cBO)
             62     {
             63         nData = cBO.nData;
             64         return *this;
             65     }
             66 
             67 public:
             68 
             69     //重載+操作符,簡單的二元操作符重載是最常見也是比較簡單的。基本思路都是這樣,注意如果
             70     //操作符出現在左邊,則只能用友員了。這里了有幾個返回類型是CBaseOperator,return
             71     //語句中卻是兩個int相加,這種情況是可以通過的,編譯器會自動構建一個相應的對象返回,
             72     //前提是你的構造函數要有相應的參數,這里是int作為參數
             73     int operator+(int nAdd) const
             74     {
             75         return nData + nAdd;
             76     }
             77 
             78     int operator+(int nAdd)
             79     {
             80         return nData + nAdd;
             81     }
             82     
             83     friend int operator+(int nAdd,const CBaseOperator& cAdd)
             84     {
             85         return nAdd + cAdd.nData;
             86     }
             87     
             88     CBaseOperator operator+(const CBaseOperator& cAdd) const
             89     {
             90         return nData + cAdd.nData;
             91     }
             92 
             93     //重載減法什么的也是一樣。就不寫了。哈哈
             94 
             95     //比較操作符重載==,!=,>, >=, <, <=總結:這里都是配套的操作一般來說如果寫一個
             96     //都會重載其他幾個,特別是==,!=。當然也有例外。哈哈。。
             97     bool operator==(const CBaseOperator& cEqual) const
             98     {
             99         return nData == cEqual.nData;
            100     }
            101     bool operator == (int nEqual) const
            102     {
            103         return nData == nEqual;
            104     }
            105     friend bool operator ==(int nEqual, const CBaseOperator& cEqual)
            106     {
            107         return cEqual.nData == nEqual;
            108     }
            109     bool operator!=(const CBaseOperator& cEqual) const
            110     {
            111         return nData != cEqual.nData;
            112     }
            113 
            114     //其他的也就不寫了,基本一樣。哈哈
            115 
            116     //重載++,--操作符,因為++,--有兩種方式,一種是前增量(++XXX先改變自己,返回),
            117     //一種是后增量(改變自己,返回改變前的狀態)
            118     //因為重載是判斷參數的,為了能區別前增量和后增量,C++的設計者做了這樣的考慮。
            119     //就是重載后增量的時候在參數列表中加一個int類型參數,這樣就避免的重載的重復了。
            120     //在調用上,如果都重載,那么用int參數的是后增量++,沒有參數的是前增量++,
            121     //(注:我在這里說的是成員函數,當然友員的重載參數個數要多一個,以后的我可別說我無知啊。)
            122     //如果都重載,那么前增量和后增量都會調用相應的函數,如果只重載了后增量,那么前增量會失敗
            123     //如果只重載了前增量,就會無論是前增量和后增量都會調用這個函數。所以一般他們也是成對
            124     //出現的,除非你懶,只寫前增量,可惜如果人家要調用后增量呢?結果會錯的哦。哈哈。
            125 
            126     //重載后增量.
            127     CBaseOperator operator++(int)
            128     {
            129         CBaseOperator cTemp = *this;
            130         ++nData;
            131         return cTemp;
            132     }
            133 
            134     //重載前增量
            135     CBaseOperator& operator++()
            136     {
            137         ++nData;
            138         return *this;
            139     }
            140 
            141     //重載--操作符是一樣的,也不寫了。
            142 
            143     //重載[],()等操作符號,同樣[]的參數個數是確定的。
            144     //我之說以把他們寫一起,是因為我錯誤的以為[]的參數個數是可以自己定義。錯了錯了。
            145     //知錯能改是好的,對了,()的參數個數是可以自己定義的。這個就給我們很大的發揮空間了。
            146     //都忘了[],() = 等操作符必須是成員函數,上面有寫。不能用友員和靜態成員函數
            147 
            148     //重載[]
            149     int operator[](int nIndex) const
            150     {
            151         return nIndex;
            152     }
            153 
            154     //重載()
            155     int operator()(int a) const
            156     {
            157         return a;
            158     }
            159 
            160     bool operator()(int a, int b) const
            161     {
            162         return a > b;
            163     }
            164 
            165     CBaseOperator operator()(int a, int b, int c)
            166     {
            167         return CBaseOperator(a+b+c+*this);
            168     }
            169 
            170     //重載*,->的操作符,*操作符就是相當于指針的*p;不過這里已經失去了原來的意義,他不是一個指針了。
            171     //但如果是想通過他來得到一些東西,也是可以的,特別在迭代器中常用這種方法。->也是和*配對出現的。
            172     //不過->操作符比較有意思,貌似和(*p).dddd真的差不多,所以返回的應該是一個結構的指針,我們這里
            173     //就返回了本身,當然可以返回任何結構的指針的。(并不是只能返回本身)。
            174 
            175     //重載*,這里參數個數是固定的,多寫一個就成了乘法的操作了。哈哈
            176     int operator*() const
            177     {
            178         return nData;
            179     }
            180 
            181     //重載->
            182     CBaseOperator* operator->()
            183     {
            184         return this;
            185     }
            186 
            187     //其他的例如&& || 這樣的操作符還是不重載的好。利用其原有的本性
            188 
            189     //重載new delete,這里編譯器做了一個限制,new必須返回void*類型, delete必須
            190     //返回void類型。(上面說過函數重載是不檢查返回類型的,和這里并沒有沖突,他只是限定了返回
            191     //類型,而不是只有返回類型不同的函數能重載,這個是編譯器做的工作,一定上確保new能更好的工作吧)
            192     //還有就是他們的參數個數都是可以自定義的。new 和 new[] 是兩個不同的操作符,所以還是要分別重載一下。
            193     //delete 和 delete[] 也是兩個不同的操作符。這里只重載了一個。
            194     void* operator new(size_t size)
            195     {
            196         
            197         return  malloc(size);
            198     }
            199 
            200     void* operator new[](size_t size)
            201     {
            202         return  malloc(size);
            203     }
            204 
            205     void operator delete(void* P, unsigned int size)
            206     {
            207         size = 0;
            208         free(P);
            209     }
            210 };
            211 
            212 int main()
            213 {
            214     const CBaseOperator cCo1(100);
            215 
            216     //判斷+重載符
            217     int nSum = cCo1 + 50;
            218     printf("%d\n", nSum);
            219     nSum = 50 + cCo1;
            220     printf("%d\n", nSum);
            221 
            222     //這里順便檢測一下拷貝構造函數
            223     CBaseOperator co2(20);
            224     CBaseOperator co3 = co2 + cCo1;
            225     nSum = co3.nData;
            226     printf("%d\n", nSum);
            227 
            228     nSum = co3 + 60;
            229     printf("%d\n", nSum);
            230 
            231     //檢測+,和=操作符
            232     co3 = 10 + cCo1 + co2 + 20;
            233     nSum = co3.nData;
            234     printf("%d\n", nSum);
            235 
            236     //查看比較操作符
            237     if (cCo1 == cCo1 && cCo1 == 100 && 100 == cCo1)
            238     {
            239         printf("True\n");
            240     }
            241     co3 = co2;
            242     if (!(co3 != co2))
            243     {
            244         printf("True\n");
            245     }
            246 
            247     //增量操作符,cCo1是不能做這個操作的,因為他是常量
            248     nSum = co2.nData;
            249     printf("%d\n", nSum);
            250     nSum = (co2++).nData;
            251     printf("%d\n", nSum);
            252     nSum = (++co2).nData;
            253     printf("%d\n", nSum);
            254 
            255     //測試[],
            256     nSum = cCo1[45];
            257     printf("%d\n", nSum);
            258 
            259     //測試()
            260     nSum = cCo1(50);
            261     printf("%d\n", nSum);
            262     
            263     if (cCo1(4523))
            264     {
            265         printf("True\n");
            266     }
            267 
            268     co2 = co3(10,20,30);
            269     nSum = co2.nData;
            270     printf("%d\n", nSum);
            271 
            272     //測試*,這里co2并不是指針哦。只是重載了*的操作符
            273     nSum = *co2;
            274     printf("%d\n", nSum);
            275 
            276     //測試->,這里也一樣。
            277     nSum = co2->nData;
            278     printf("%d\n", nSum);
            279 
            280     //測試new new[] delete,
            281     //這里沒有測試輸出。單步就知道了。
            282     CBaseOperator* pCb1 = new CBaseOperator();
            283     CBaseOperator* pCb2 = new CBaseOperator[10];
            284     delete pCb1;
            285     delete pCb2;
            286 
            287     system("pause");
            288     return 0;
            289 }
            290 

            posted on 2009-04-01 13:10 shongbee2 閱讀(19696) 評論(8)  編輯 收藏 引用 所屬分類: c/c++

            評論

            # re: c++操作符重載 2009-04-01 22:52 Herb

            如果理解了,可能就幾句就說清了,如果不理解,可能就是長篇大論。  回復  更多評論   

            # re: c++操作符重載 2009-04-01 23:59 shongbee2

            @Herb
            貌似我沒有懂大俠的話!您的意思是我寫的啰嗦了是吧!呵呵,謝謝啦。
            我語文很爛,不過我會努力改正的。呵呵。耽誤了您的時間,抱歉哈。  回復  更多評論   

            # re: c++操作符重載 2009-04-15 16:04 yatou

            哈~看完了,學到不少東西了~謝謝啦~  回復  更多評論   

            # re: c++操作符重載 2009-04-17 01:16 shongbee2

            @yatou
            呵呵,能給你帶來幫助是對我最大的獎賞。加油。  回復  更多評論   

            # re: c++操作符重載 2009-05-14 12:08 tw

            感謝你與大家分享  回復  更多評論   

            # re: c++操作符重載 2010-03-11 09:48

            很好,呵呵  回復  更多評論   

            # re: c++操作符重載 2012-03-20 16:10 wenxin

            收益了  回復  更多評論   

            # re: c++操作符重載 2012-04-19 22:45 張永昌

            其實,c++標準庫有內建的工具幫你生成其它的所有大小的操作符,只需要重載其中的兩個比較操作符就可以了,根據你的語義可以采用,沒必要寫這么多的代碼。  回復  更多評論   

            久久久久亚洲精品天堂| 色99久久久久高潮综合影院| 蜜臀av性久久久久蜜臀aⅴ麻豆| 色偷偷偷久久伊人大杳蕉| 久久综合给久久狠狠97色| 国产成人精品免费久久久久| 久久久九九有精品国产| 久久久久无码国产精品不卡| 久久久久久精品无码人妻| 伊人久久综在合线亚洲2019| 日本精品久久久久影院日本 | 久久久久免费精品国产| 久久人人爽人人爽AV片| 99久久99久久久精品齐齐| 久久婷婷人人澡人人| 99久久无码一区人妻a黑| 久久综合伊人77777| 亚洲国产精久久久久久久| 国产亚洲精品久久久久秋霞| 久久精品成人免费网站| 香蕉久久夜色精品升级完成| 亚洲精品国产综合久久一线| 国内精品久久人妻互换| 久久妇女高潮几次MBA| 久久人人爽人人爽人人片AV麻豆 | 777午夜精品久久av蜜臀| 久久香蕉一级毛片| 色狠狠久久AV五月综合| 久久亚洲精品国产亚洲老地址 | 久久亚洲国产欧洲精品一| 亚洲精品无码成人片久久| 久久久久久久综合狠狠综合| 美女久久久久久| 久久精品无码av| 日本国产精品久久| 久久综合鬼色88久久精品综合自在自线噜噜 | 亚洲国产精品久久久久婷婷软件 | 久久九九久精品国产| 久久亚洲国产精品一区二区| 色综合色天天久久婷婷基地| 精品国产福利久久久|