轉換建構函式和型別轉換運算子共同定義了類型別轉換(class-type conversions)。
型別轉換運算子
型別轉換運算子是類的一種特殊成員函式,它負責將乙個類型別的值轉換成其他型別。型別轉換函式的一般形式如下所示:
operator
type
() const;
其中type表示某種型別。型別轉換運算子可以面向任意型別(除一void之外)進行定義,只要該型別能作為函式的返回型別。
型別轉換運算子既沒有顯式的返回型別,也沒有形參,而且必須定義成類的成員函式。
乙個型別轉換函式必須是類的成員函式;它不能宣告返回型別,形參列表也必須為空。型別轉換函式通常應該是const。
儘管編譯器一次只能執行乙個使用者定義的型別轉換,但是隱式的使用者定義型別轉換可以置於乙個標準(內建)型別轉換之前或之後,並與其一起使用。
因為型別轉換運算子是隱式執行的,所以無法給這些函式傳遞實參,當然也就不能在型別轉換運算子的定義中使用任何形參。同時,儘管型別轉換函式不負責指定返回型別,但實際上每個型別轉換函式都會返回乙個對應型別的值。
和使用過載運算子的經驗一樣,明智地使用型別轉換運算子也能極大地簡化類設計者的工作,同時使得使用類更加容易。然而,如果在類型別和轉換型別之間不存在明顯的對映關係,則這樣的型別轉換可能具有誤導性。
型別轉換運算子可能產生意外結果
在實踐中,類很少提供型別轉換運算子。在大多數情況下,如果型別轉換自動發生,使用者可能感覺比較意外,而不是感覺受到了幫助。然而這條經驗法則存在一種例外情況:對於類來說,定義向bool的型別轉換還是比較普遍的現象。
在c++標準的早期版本中,如果類想定義乙個向bool的型別轉換,則它常常遇到乙個問題:因為bool是一種算術型別,所以類型別的物件轉換成bool後就能被用在任何需要算術型別的上下文。這樣的型別轉換可能引發意想不到的結果,特別是當istream含有向bool的型別轉換時,下面的**仍將通過編譯:
int i = 42;
cin<< i;// 如果向bool的型別轉換不是顯式的,則該**在編譯器看來將是合法的!
這段程式試圖將輸出運算子作用於輸入流。因為istream本身並沒有定義<<,所以本來**應該產生錯誤。然而,該**能使用istream的bool型別轉換運算子將cin轉換成bool,而這個bool值接著會被提公升成int並用作內建的左移運算子的左側運算物件。這樣一來,提公升後的bool值(1或0)最終將會被左移42個位置。
顯式的型別轉換運算子
為了防止這樣的異常情況發生,c++11新標準引入了顯式的型別轉換運算子(explicit conversion operator):
class smallint
...};
和顯式的建構函式一樣,編譯器(通常)也不會將乙個顯式的型別轉換運算子用於隱式型別轉換。
該規定存在乙個例外,即如果表示式被用作條件,則編譯器會將顯式的型別轉換自動應用於它。
轉換為bool
在標準庫的早期版本中,io型別定義了向void*的轉換規則,以求避免上面提到的問題。在c++11新標準下,io標準庫通過定義乙個向bool的顯式型別轉換實現同樣的目的。
向bool的型別轉換通常用在條件部分,因此operator bool() const一般定義成explicit。
過載 型別轉換與運算子
前面我們看到由乙個實參呼叫的非顯式建構函式定義了一種隱式的型別轉換,這種建構函式將實參型別的物件轉換成類型別。我們同樣能定義對於類型別的型別轉換,通常定義型別轉換運算子可以做到這一點。轉換建構函式和型別轉換運算子共同定義了類型別轉換,這樣的轉換有時也被稱作使用者定義的型別轉換。型別轉換運算子 型別轉...
型別轉換 運算子過載
c 中沒有返回型別的函式有3個,建構函式 析構函式 型別轉換函式。operator const char const 如果是過載 的話,那應該寫成 const char operator const而上面所寫的那樣,而且即使是這樣寫那也不正確的,因為運算子過載中有幾個運算子的返回值是有格式的 約定 ...
C 運算子過載與型別轉換
當乙個過載的運算子是成員函式時,this繫結到左側運算物件。成員運算子函式的 顯式 引數數量比運算物件的數量少乙個。通常情況下,不應該過載逗號 取位址 邏輯與和邏輯或運算子。關於過載運算子的返回型別 應與其內建版本的返回型別相容 邏輯和關係運算子應該返回bool,算術運算子應該返回乙個類型別,賦值運...