C++筆記(三)重載操作符

1.操作符重載:把操作符賦予新的意義

2.可重載和不可重載


3.用於內置類型的操作符,其含義不能改變。例如,內置的整型加號操作符不能重定義:int oprator+(int,int);//error:cannot redefine built-in operator for ints

 也不能爲內置數據類型重定義加號操作符。例如,不能定義接受兩個數組類型操作數的operator+。

4.操作符的優先級、結合性或操作數數目不能改變。不管操作數的類型和操作符的功能定義如何,例如:x == y + z;  總是將y和z綁定到operator+,結果再作爲operator==的右操作數。同時也不具備短路求值特性,例如:&&和||重載後,兩個操作數都會進行求值。

5.當操作符重載函數作爲類的成員函數時,操作符重載函數的參數會比作爲友元或者獨立於類的操作符重載函數少一個參數,因爲操作符重載類成員函數把調用該函數的第一個類的對象作爲函數的第一個參數,也就是隱含的this指針指向調用該函數的第一個對象,所以會少一個參數。

例如:item& item::operator+(const item&);//成員

           item operator+(const item&,const item&);//非成員

6.操作符定義爲非成員函數時,通常必須將它們設置爲所操作類的友元,在這種情況下,操作符通常需要訪問類的私有部分。友元部分見上一篇博文C++筆記(二)友元

7.某些情況下操作符函數必須返回一個對象類型作爲返回值,比如item對象,a=b+c;重載+操作符就必須返回一個item類型的對象,以便賦給對象a,不然該語句就會出錯。當然你可以在語句中返回一個臨時對象,也可以返回一個對象的引用,或者返回this指針,不過返回臨時對象會浪費內存開銷,所以最好返回類對象的一個引用。

8.操作符函數可以按值傳遞也可以按引用傳遞,這根據操作符而定,比如對於+運算符既可以把對象按值傳遞給操作符函數也可以按引用傳遞給操作符函數,而且+操作符不會改變原操作數的值,所以應把傳遞類型生命爲const,例如:item operator+(const item& a,const item& b)。但對於要改變其自身值的操作符比如++運算符,就必須傳遞引用,且不能把該引用聲明爲const類型,因爲如果操作數按值傳遞的話,傳遞給操作數函數的將是一個對象的副本,兩個副本是獨立的,不能改變到遠對象的值,所以應按引用傳遞對象,

例如:item operator++(item& a)。

9.輸入和輸出操作符:

支持I/O操作的類所提供的I/O操作接口,一般應該與標準庫iostream爲內置類型定義的接口相同,因此,許多類都需要重載輸入和輸出操作符。IO操作符必須爲非成員函數。

輸出操作符<<的重載:爲了與IO標準庫一致,操作符應接受ostream&作爲第一個形參,對類類型const對象的引用作爲第二個形參,並返回對ostream形參的引用。

ostream& operator<<(ostream& out,const item& s)

{

out<<s.isbn<<"\t"<<s.units_sold<<"\t"<<s.revenue<<"\t"<<s.avg_prive();

return out;

}

輸入操作符>>的重載:與輸出操作符類似,但是輸入操作符必須處理錯誤和文件結束的可能性。

istream& operator>>(istream& in,item& s)

{

double price;

in>>s.isbn>>s.units_sold>>price;

if(in)

s.revenue = s.units_sold * price;

else

s = item();//相當於復位

return in;

}

10.算術操作符:

算術操作符一般定義爲非成員函數。

item operator+(const item& lhs,const item& rhs)

{

item ret(lhs);

ret += rhs;

return ret;

}

加法操作符不改變操作數的狀態,操作數是對const對象的引用;相反它產生並返回一個新的item對象,該對象初始化爲lhs的副本。我們使用item的符合賦值操作符來加入rhs的值。注意,爲了與內置操作符保持一致,加法返回一個右值,而不是一個引用。

11.相等操作符:

比較對象中的每個數據成員,如果所有對應成員都相同,則認爲兩個對象相等。

inline bool operator==(const item &lhs,const item &rhs)

{

return lhs.units_sold == rhs.units_sold && lhs.revenue == rhs.revenue && lhs.same_isbn(rhs);

}

inline bool operator!=(const item &lhs,const item &rhs)

{

return !(lhs ==rhs);

}

12.賦值操作符:

類賦值操作符接受類類型形參,通常,該形參是對類類型的const引用,但也可以是類類型或對類類型的非const引用。如果沒有定義這個操作符,則編譯器將合成它。類賦值操作符必須是類的成員,以便編譯器可以知道是否需要合成一個。

class string

{

public:

string& operator=(const string&);   //s1 = s2;

string& operator=(const char*);   //s1 = "str";

string& operator=(char);   //s1 = 'c';

//......

};

注:賦值操作符可以重載。無論形參爲何種類型,賦值操作符必須定義爲成員函數,這一點與複合賦值操作符(+=)有所不同。

賦值必須返回對*this的引用:

string賦值操作符返回string引用,這與內置類型的賦值一致。而且,因爲賦值返回一個引用,就不需要創建和撤銷結果的臨時副本。返回值通常是左操作數的引用。

例如:

item& item::operator+=(const item& rhs)

{

units_sold += rhs.units_sold;

revenue += rhs.revenue;

return *this;

}

一般而言,賦值操作符與符合操作符應返回左操作數的引用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章