C++操作符重載實(shí)際操作方法解析
C++編程語言發(fā)展至今已經(jīng)成為了開發(fā)領(lǐng)域中一個(gè)重要的應(yīng)用語言。其中有很多比較高深的內(nèi)容還值得我們?cè)趯?shí)踐中去不斷的探索。在這里我們就先從對(duì)C++操作符重載的應(yīng)用方式的了解來進(jìn)一步解讀這一編程語言。#t#
一、為什么使用C++操作符重載?
對(duì)于系統(tǒng)的所有操作符,一般情況下,只支持基本數(shù)據(jù)類型和標(biāo)準(zhǔn)庫中提供的class,對(duì)于用戶自己定義的class,如果想支持基本操作,比如比較大小,判斷是否相等,等等,則需要用戶自己來定義關(guān)于這個(gè)操作符的具體實(shí)現(xiàn)。比如,判斷兩個(gè)人是否一樣大,我們默認(rèn)的規(guī)則是按照其年齡來比較,所以,在設(shè)計(jì)person 這個(gè)class的時(shí)候,我們需要考慮操作符==,而且,根據(jù)剛才的分析,比較的依據(jù)應(yīng)該是age。那么為什么叫重載呢?這是因?yàn)?,在編譯器實(shí)現(xiàn)的時(shí)候,已經(jīng)為我們提供了這個(gè)操作符的基本數(shù)據(jù)類型實(shí)現(xiàn)版本,但是現(xiàn)在他的操作數(shù)變成了用戶定義的數(shù)據(jù)類型class,所以,需要用戶自己來提供該參數(shù)版本的實(shí)現(xiàn)。
二、如何聲明一個(gè)C++操作符重載?
A:操作符重載實(shí)現(xiàn)為類成員函數(shù)
重載的操作符在類體中被聲明,聲明方式如同普通成員函數(shù)一樣,只不過他的名字包含關(guān)鍵字operator,以及緊跟其后的一個(gè)c++預(yù)定義的操作符。可以用如下的方式來聲明一個(gè)預(yù)定義的==操作符:
- class person{
- private:
- int age;
- public:
- person(int a){
- this->aage=a;
- }
- inline bool operator ==(const person &ps) const;
- };
C++操作符重載實(shí)現(xiàn)方式如下:
- inline bool person::operator==(const person &ps) const
- { if (this->age==ps.age)
- return true;
- return false;
- }
調(diào)用方式如下:
- #include
- using namespace std;
- int main()
- { person p1(10);
- person p2(20);
- if(p1==p2) cout<<”the age is equal!”<return 0;
- }
這里,因?yàn)閛perator ==是class person的一個(gè)成員函數(shù),所以對(duì)象p1,p2都可以調(diào)用該函數(shù),上面的if語句中,相當(dāng)于p1調(diào)用函數(shù)==,把p2作為該函數(shù)的一個(gè)參數(shù)傳遞給該函數(shù),從而實(shí)現(xiàn)了兩個(gè)對(duì)象的比較。
考慮如下的if語句:
- if(10==p1) cout<<”the age is equal!”<
是否回正確執(zhí)行呢?
答案是不會(huì)的,因?yàn)橹挥凶蟛僮鲾?shù)是該類類型的對(duì)象的時(shí),才會(huì)考慮作為類成員重載操作符。因?yàn)?0不是person類型的對(duì)象,所以,不能調(diào)用classperson的操作符==。
考慮如下if語句:
- if(person(10)==person(11))
- cout<<"ok"<
是否能夠正確執(zhí)行呢?答案是可以,因?yàn)椴僮鞣麅蛇吘菬o名對(duì)象。重載的操作符并不要求兩個(gè)操作數(shù)的類型一定相同。例如:我們可以為class person定義下標(biāo)操作符,以表示該person和電話的對(duì)應(yīng)關(guān)系:
- /*實(shí)現(xiàn)下標(biāo)操作符*/
- #include
- #include
- using namespace std;
- class person
- { private:
- int tel;
- public:
- int & operator[](string const & nm)
- {
- return tel;
- }
- int GetTel()
- {
- return tel;
- }
- };
- int main()
- {
- person p1;
- p1["suo"]=110;
- person p2;
- p2["rose"]=120;
- cout<cout<return 0;
- }
對(duì)于重載為成員函數(shù)方式的操作符,隱式的this指針被作為該函數(shù)的第一個(gè)參數(shù),來代表左操作數(shù)。
B:C++操作符重載實(shí)現(xiàn)為非類成員函數(shù)(全局函數(shù))
對(duì)于全局重載操作符,代表左操作數(shù)的參數(shù)必須被顯式指定。例如:
- #include
- #include
- using namespace std;
- class person
- {
- public:
- int age;
- public:
- };
在類的外部,不能訪問該類私有數(shù)據(jù),所以,要把a(bǔ)ge設(shè)置為public
- bool operator==(person const &p1 ,person const & p2)
- {
- if(p1.age==p2.age)
- return true;
- return false;
- }
- int main()
- {
- person rose;
- person jack;
- rose.age=18;
- jack.age=23;
- if(rose==jack)/*兩個(gè)對(duì)象分別代表左右操作數(shù)*/
- cout<<"ok"<return 0;
- }
C:如何決定把一個(gè)操作符重載為類成員函數(shù)還是全局名字空間的成員呢?
①如果一個(gè)重載操作符是類成員,那么只有當(dāng)與他一起使用的左操作數(shù)是該類的對(duì)象時(shí),該操作符才會(huì)被調(diào)用。如果該操作符的左操作數(shù)必須是其他的類型,則操作符必須被重載為全局名字空間的成員。
②C++要求賦值=,下標(biāo)[],調(diào)用(), 和成員指向-> 操作符必須被定義為類成員操作符。任何把這些操作符定義為名字空間成員的定義都會(huì)被標(biāo)記為編譯時(shí)刻錯(cuò)誤。
③如果有一個(gè)操作數(shù)是類類型如string類的情形那么對(duì)于對(duì)稱操作符比如等于操作符最好定義為全局名字空間成員。
D:操作符重載為友元函數(shù)方式
如果把C++操作符重載為友元函數(shù)方式,則在該函數(shù)的內(nèi)部,可以直接訪問授權(quán)類的私有數(shù)據(jù)成員,這是友元函數(shù)方式和全局名字空間方式的主要區(qū)別。
E:怎樣判斷一個(gè)非類成員的操作符應(yīng)該是類的友元還是應(yīng)該使用成員訪問函數(shù)呢?一般來說,類的實(shí)現(xiàn)者應(yīng)該盡量使得名字空間函數(shù)和訪問類內(nèi)部表示的操作符的數(shù)目最小化。如果已經(jīng)提供了訪問成員函數(shù)并且它們具有等同的效率,那么最好是使用這些成員函數(shù)。但是如果類的實(shí)現(xiàn)者決定不為該類的某些私有成員提供訪問成員函數(shù)而且名字空間操作符需要引用這些私有成員才能完成,它們的操作那么就必須使用友元機(jī)制。例如:
- #include
- #include
- using namespace std;
- class person{
- public:
- int age;
- public:
- };
- bool operator==(person const &p1 ,person const & p2)
- {
- if(p1.age==p2.age) return true;
- return false;
- }
- ostream operator<<(ostream &os,person const &p)
- {
- os<<"the person age is:"<return os;
- }
- int main()
- {
- person rose;
- person jack;
- rose.age=18;
- jack.age=23;
- cout</*call ostream operator<<(ostream &os,person const &p) */
- cout<return 0;
- }
三、C++操作符重載的設(shè)計(jì)
①類的設(shè)計(jì)者不能聲明一個(gè)沒有預(yù)定義的重載操作符。
②不能為內(nèi)置數(shù)據(jù)類型定義其他的操作符。
③預(yù)定義的操作符優(yōu)先級(jí)不能被改變。
④一個(gè)類最終需要提供哪些操作符,是由該類預(yù)期的用途來決定的。
四、prefix and postfix
為區(qū)分后置操作符與前置操作符的聲明,重載的遞增和遞減后置操作符的聲明有一個(gè)額外的int 類型的參數(shù)。這里不需要給出參數(shù)名,因?yàn)樗鼪]有被用在操作符定義中。額外的整型參數(shù)對(duì)于后置操作符的用戶是透明的,編譯器為它提供了缺省值因而該參數(shù)也可以被忽略。例如:
- #include
- #include
- using namespace std;
- class person
- {
- private:
- int age;
- public:
- person(int a)
- {
- aage=a;
- }
- person const operator++()/*prefix ++ */
- {
- this->age++;
- return *this;
- }
- person const operator++(int a)/*postfix ++ */
- {
- person temp(1);
- temp=*this;
- this->age++;
- return temp;
- }
- int GetAge()
- {
- return age;
- }
- };
- int main()
- {
- person rose(10);
- person jack(20);
- person marry(22);
- person tom(30);
- jack=++rose;
- marry= tom++;
- return 0;
- }
以上就是對(duì)C++操作符重載的相關(guān)介紹。