運算子過載(operator overload) 是c++的乙個重要的新特性,它使得程式設計師把c++運算子定義擴充套件到運算元是物件的情況.運算子過載的目的是使c++程式更加直觀,更易懂.
但這種方便有時候也帶來一些潛在的危險!!
運算子過載和普通的過載一樣:
作用域相同,函式名字相同, 但引數不同(引數個數,引數的型別) , 注意如果函式名字相同,引數相同但函式的返回值型別不同這不是過載,這是錯誤!
格式:返回值型別 operator被過載的運算子 (引數 ...) ;
具體的例子網上有很多 , 我的重點是一些我們在寫過載中易忽略的一些小問題.
有時候我們的程式在多數情況下是對的但有時也總有一些出乎我們意料的情況:
請看下面這個程式:
#include#includeusing namespace std;
int explicit add(int a,int b) //1
運算結果:
我本以為第二個cout會呼叫第二個函式結果, 但結果程式呼叫的是第乙個
這裡涉及到型別轉換編譯器缺省會把
1 .1 -> 1 (double->int) 向下轉換.
而不是把 2->2.0 (int -> double ) 這樣是強制型別轉換.
那麼如何避免編譯器的隱藏型別轉換了
那就是 explicit (
清晰的)
關鍵字這個關鍵字的作用是告訴編譯器禁止預設的型別轉換, 從而導致一些非法的引數被預設轉換成為合法的引數. 我在opencv的標頭檔案中見到了很多這個關鍵字, 可見這個關鍵字還是很重要的.
這是加上explicit關鍵字後的結果:
該錯誤在編譯階段就暴露出來 如果是在執行階段出現這麼乙個錯誤,呵呵 累死你興許也找不到原因!
#include#includeusing namespace std;
//乙個複數類
class complex
; complex(double,double);
complex operator++(int);
complex& operator++();
complex& operator--();
complex operator+(const complex &);
complex operator-(const complex &);
complex operator*(const complex &);
//complex& operator+=(complex &);
//complex& operator-=(complex &);
//iostream & operator<
//iostream & operator>>(iostream &);
double getreal();
double getimage();
//private:
double real;
double image;
};complex::complex(double r,double i)
;complex& complex::operator++()
complex complex::operator++(int a)
complex& complex::operator--()
;complex complex::operator+(const complex &a)
;complex complex::operator-(const complex &a)
; complex complex::operator*(const complex &a)
;/*complex& complex::operator+=(complex &a)
;*//*complex& complex::operator-=(complex &a)
;*/complex& operator+=(complex &a,const complex &b)
;complex& operator-=(complex &a,const complex &b)
;ostream &operator<
;int main()
{ complex a;
cout
cout<
可能有人會說這個程式有什麼特別的呢?
你可能會注意到這個程式裡有好多引用& , 但有的函式返回值前加上了引用 ,有的沒有加.
我先說一下 ,可能有些人不知道為什麼要加引用,有時候在函式傳參時加不加結果都是那,
的確你的程式並沒有錯.
如果不加引用 ,乙個函式在傳引數的時候和返回的時候都會呼叫該物件所屬類的拷貝建構函式構造出乙個臨時物件出來. 如果這個類不是很複雜的話這點開銷也許不算什麼,但如果這個類很複雜的話這點開銷你就得注意了.所以所有能加引用的地方盡量就使用它吧.
但我寫的上面這個程式為什麼有的地方 沒有加引用了?
你仔細看就會發現這些函式的返回值,都有乙個共性就是他們都返回了乙個在該函式中建立的乙個區域性的變數. 該物件(變數) 在函式返回時生命週期結束,它所占用的記憶體空間就會被釋放掉, 你所返回的東西已經不存在了 , 所以這裡千萬不能加引用.
不加引用 函式在返回時會構造出另為乙個該類的物件,新物件的作用域和呼叫它的地方所在的作用域不相同,所有你就可以使用這個新的物件了,但必須在呼叫它的地方的作用域中新建乙個物件呼叫它的複製函式來接收返回的臨時物件.
函式在返回的時候會構造出乙個新的物件 該物件也是臨時的 , 也就是說在返回乙個函式中的區域性變數的時候不能用引用或指標來指向它 ,因為這樣做的後果是不確定的
上面的東西是我在學習實踐的過程中不斷總結發現的, 隨著知道的更多 對原來東西的理解也在變化.以上純屬個人見解,如果有不合理的地方我會慢慢改正的.
C 運算子過載需要注意的地方
有時候自己寫乙個類,需要過載運算子,但對於一些操作符 如 等 可以在類裡寫,也可以在類外寫。那麼 c 編譯器會去怎麼呼叫呢?首先,我們知道,過載 機制可以允許多個函式有相同的函式名,但引數列表必須不同。c 編譯器經過名字改編 name mangling 可以在呼叫時依據所傳實參找到 最符合 的函式實...
位運算子 需要注意的地方
本人第乙個部落格,以後會經常寫 此時的我就像戲台上的老將軍 以免第二次犯同樣的錯誤。因為考研的原因,好久沒有coding了,略感生疏。瘋玩了十幾天,決定拿起書本,紮實地重新看一遍專業書。從開始學習程式設計起,就不是很注重位運算,因為覺得可以用別的方法代替。後來發現有些東西用位運算處理更有效率。這裡主...
運算子過載 的注意
操作符過載函式不能為友元函式,只能為某類中的成員函式.假如將賦值運算子過載為dog類的友元 friend dog operator dog d1,dog d2 例如有表示式 x y 可以正確的將y賦值給x x,y都是dog類的物件。又例如有一表示式99 y 它被解釋為operator 99,y c ...