一、操作符函式過載
什麼是操作符函式:在c++中針對類型別的物件的運算子,由於它們肯定不支援真正的運算操作,因此編譯器會將它們翻譯成函式,這種就叫作操作符函式(運算子函式)。
編譯器把運算翻譯成運算子函式,可以針對自定義的類型別設計它獨有的運算功能。
其實各種運算已經具備一些功能,再次實現它的就是叫作運算子過載。
雙目運算子:
a+b成員函式
a.operator+(b);
全域性函式
operator+(a,b);
單目運算子:
!a成員函式
a.operator!(void);
全域性函式
operator!(a);
二、雙目操作符函式過載
成員函式:
const 類 operator#(const 類& that) const
注意:雙目錄運算子的運算結果是個右值,返回值應該加 const,然後為了const物件能夠呼叫引數應寫 const,函式也應該具備 const 屬性。
全域性函式:
const 類 operator#(const 類& a,const 類& b)
注意:全域性函式不是函式,可能會訪問類的私有成員,解決這種問題可以把函式宣告為類的友元函式(友元不是成員)。
友元:在類的外部某個函式中想訪問類的私有成員(public/protected/private)時,需要所在的函式宣告為友元,但友元只是朋友,因此它只有訪問權,沒有實際的擁有權(其根本原因是它沒 this 指標)。
友元宣告:把函式的宣告寫乙份到類中,然後在宣告前加上 friend 關鍵字,使用友元既可把操作符函式定義為全域性的,也可以確保類的封裝性。。
注意:友元函式與成員函式不會構成過載關係,因為它們不在同乙個作用域內。
三、賦值型別的雙目操作符
成員函式
類& operator#(const 類& that)
全域性函式
類& operator#(cosnt 類& a,const 類& b)
1、獲取單參構造成賦值運算的呼叫方式。
string str = 「sunll」; // 會呼叫單參構造,而不呼叫賦值運算子
str = 「hehe」;
2、左運算元據不能具有 const 屬性
1、成員函式不能是常函式
2、全域性函式第乙個引數不能有 const 屬性
四、單目操作符函式過載
成員函式
const 類 operator#(void) const
全域性函式
const 類 operator#(const 類& that)
前++/–
類& operator#(void)
類& operator#(類& that)
後++/–(啞元)
const 類& operator#(int)
const 類& operator#(類& that,int)
五、輸入輸出操作符過載
cont 是 ostream 型別的物件,cin 是 istream 型別的物件。
如果<</>>運算實現為成員函式,那麼呼叫者應該是ostream/istream,而我們無權增加標準庫的**,因此輸人/輸出運算子只能定義為全域性函式。
ostream& operator<<(ostream& os,const 類& p)
istream& operator>>(istream& is,類& p)
注意:在輸入輸出過程中,cin/cout會記錄錯誤標誌,因此不能加 const 屬性。
六、特殊操作符的過載
1、下標操作符的過載;常用於在容器型別中以下標方式獲取元素。
型別& operator(int i)
返回值應該是乙個引用。
2、函式操作符(),乙個類如果過載函式操作符,那麼它的物件就可以像函式一樣使用,引數的個數與返回值型別可以不確定。它是唯一乙個可以引數有預設的操作符。
3、解引用運算子 ,成員訪問操作符 ->
如果乙個類過載了和->,那麼它的物件就可以像指標一樣使用
所謂的智慧型指標就是一種類物件,它支援解引用和成員訪問操作符
4、智慧型指標
常規指標的確定:
當乙個常規指標離開它的作用域時,只有該指標所占用的空間會被釋放,而它指向的記憶體空間能否被釋放不確定,在一些特殊情況下(人為/業務邏輯的特殊性)free或delete沒有執行。就會形成記憶體洩露
智慧型指標的優點
是一種封裝了常規指標的類型別物件,當它離開作用域時,它的析構函式會自動執行,它的析構函式會負責釋放常規指標所指向的動態記憶體(以正確方式建立的智慧型指標,它的析構函式才會正確執行)
相同點:
都支援*和->運算
不同點:
任何時候乙個物件只能使用乙個智慧型指標來指向,而常規指標可以指向多次
智慧型指標的賦值操作需要經過拷貝構造/賦值構造特殊處理(深拷貝)
auto_ptr:標準庫中封裝好的智慧型指標,實現了常規指標的基本功能
標頭檔案:
用法:auto_ptr《指向的型別》 指標變數名(物件的位址)
auto_ptr的侷限性:
不能跨作用域使用,一旦離開作用域指標變數會釋放,它指向的物件也會釋放
不能放入標準容器
不能指向物件陣列
5、new/delete/new/delete運算子過載
1、c++預設的堆記憶體管理器速度較慢,過載 new/delete 底層使用 malloc/free可以提高執行速度。
2、new在失敗時會產生異常,而每次使用new時為了安全都應該進行異常捕獲,而過載new操作符只需要在操作符函式中進行一次錯誤處理即可
3、一些佔位元組數比較小的類,頻繁使用new,可能會大量的記憶體碎片,而過載new操作符後,可以適當的擴大每次申請的位元組數,減少記憶體碎片產生的機率
4、過載 new/delete 可以記錄堆記憶體使用的資訊
5、過載 delete 可以檢查到釋放記憶體失敗的資訊,檢測到記憶體洩露。
關於操作符過載的建議:
1、在過載操作符時要根據操作符實際的功能和意義來確定具體引數,返回值,是否具有 const 屬性,返回值是否是引用或者是臨時物件。
2、過載操作符要符合情理(要有意義),要以實際用途為前提前。
3、過載操作符的意義是為了讓物件的操作更簡單、方便、提高**可讀性,而不是為了炫技。
++n;
4、過載操作符要與預設的操作符的功能、運算規則一直,不要出現***的操作
七、過載操作符的限制
1、不能進行過載的操作符:
域限定符 ::
直接成員訪問操作符 .
條件表示式 ?:
位元組長度操作符 sizeof
型別資訊操作符 typeid
2、過載操作符不能修改操作符的優先順序
3、無法過載所有基本型別的操作符運算子
4、不能修改操作的引數個數
5、不能發明新的操作符
操作符過載
ifndef vertex h define vertex h class vertex vertex float px float py float pz vertex operator const vertex p vertex operator const vertex p void oper...
操作符過載
1.操作符是靜態方法,返回值表示操作結果,引數是運算元。2.操作符過載需要在過載的操作符前加上operator關鍵字。3.最好少用操作符過載,只有在意義明晰而且與內建類的操作一致時才適合使用,以免造成混亂。以建立的分數類 fraction 中的 為例,該分數類中有兩個int型的私有屬性 分子 num...
過載操作符
1.過載操作符1.1 限制過載操作符具有以下限制 1 只有c 預定義的操作符集中的操作符才可以被過載 2 對於內建型別的操作符,它的預定義不能被改變,應不能為內建型別過載操作符,如,不能改變int型的操作符 的含義 3 也不能為內建的資料型別定義其它的操作符 4 只能過載類型別或列舉型別的操作符 5...