C++第十一章筆記
類就像伺服器給客戶開了一個玩笑,然後想盡千方百計的圓這個謊。
運算子過載
運算子過載就是C++中多型的另一種表現,目的是讓類使用起來更自然。
使用方法,類內過載:
返回值 operator運算子(引數);
比如,對於類A:
A operator + (int n);
使用就可以
A tmp;
int n;
tmp = tmp + n;
但是n+tmp是錯誤的,因為類內過載說白了還是成員函式,運算子左面就是第一個引數,也就是物件本身,運算子右面就是過載運算子函式的引數。如果需要反過來,可以用類外過載(非成員函式過載),也就是通過友元函式。
以下10種運算子不允許過載(不允許過載的運算子):
. :成員運算子
?: :條件運算子
siezof::sizeof運算子
:: :作用域解析運算子
.* :成員指標運算子
typeid:一個RTTI運算子
const_cast:強制轉換運算子
dynamic_cast:強制轉換運算子
teinterpret_cast:強制轉換運算子
static_cast:強制轉換運算子
友元函式
友元有3種:友元函式,友元類,友元成員函式。
通過函式稱為類的友元,可以賦予該函式與類的成員函式相同的訪問許可權,這裡主要寫友元函式。
為了解決上文的問題,其實大部分運算子都可以類外過載。以此來交換傳參的順序。
友元就是在成員函式最前面加個friend。
這樣,這個函式就不是成員函式,就不能用成員運算子呼叫
雖然不是成員函式,但是他卻又類作用域。
因為不是成員函式,所以編寫函式定義的時候不需要加作用域限定符,不要再定義的時候加friend。
過載ostream & operator(ostream &os,A b)
{
os
當然,這個過載要作為A的友元才能方法A的私有成員資料。當然,如果A類有返回要列印的資料的函式,過載不一定必須是友元。換句話說,只要能打印出資料,是不是友元無所謂,我們過載operator TypdName();
注意:
- 轉換函式必須是類方法
- 轉換函式不能指定返回型別
- 轉換函式不能有引數
比如:
operator double();
使用起來也比較奇葩,比如對於類A:
A tmp = 1.2;
double tt = double(tmp);
這就是為什麼說更像資料型別過載而不是強制轉換了。
但是還要注意的是:沒有返回型別不是沒有return,要不然,強制轉換之後,到底賦值賦的什麼呢?還是靠return控制的,只是在宣告和定義中不寫罷了。
當然,轉換函式有了,顯式隱式轉換都無所謂了,因為都可以實現。
最後一點,一定要注意好轉換中的二義性,比如,定義了int和double轉換函式,卻給一個long賦值,會怎麼樣呢?
如果只有一個轉換函式,那麼語法沒有錯誤,int或double對long都是合法的,但如果都存在,則編譯器無法判斷使用哪個過載,便報錯,對於這種情況,要麼就再定義一個long 的轉換函式,要麼直接使用強制轉換。
One more thing
如果轉換函式和友元函式聯合起來,效果是驚人的。一個可以控制型別的轉換,一個可以進行運算等操作。
但是,過多的轉換函式卻很容易導致二義性,所以說,玩火謹防尿床。
但還是分析一下:
如果依賴隱式轉換完成運算,程式更簡短,定義的函式更少,出錯機率也就小但是每次轉換的時候都將呼叫轉換建構函式,這增加時間和記憶體開銷。反之,利用過載運算子,程式設計師需要完成的工作更多,但程式執行速度較快。
歡迎到微信裡去當吃瓜群眾