1. 程式人生 > >C++第十一章筆記

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

如果轉換函式和友元函式聯合起來,效果是驚人的。一個可以控制型別的轉換,一個可以進行運算等操作。

但是,過多的轉換函式卻很容易導致二義性,所以說,玩火謹防尿床。

但還是分析一下:

如果依賴隱式轉換完成運算,程式更簡短,定義的函式更少,出錯機率也就小但是每次轉換的時候都將呼叫轉換建構函式,這增加時間和記憶體開銷。反之,利用過載運算子,程式設計師需要完成的工作更多,但程式執行速度較快。


歡迎到微信裡去當吃瓜群眾