由ios學到的C 使用者自定義轉換

2022-05-10 04:51:25 字數 1526 閱讀 2313

與學長在群裡討論到了iostream的》操作符的返回值問題,記得曾經找資料的時候有說過》返回的是流引用,不過可以被轉換成bool,因此可以被直接用在while中作為條件。當時就記得有這麼回事,也沒有繼續深入;今天正好藉此機會好好補一補,心得記錄下來,備用。

//in vc6.0

operator void *() const

bool operator!() const

在vc6裡上面的兩個函式是在class ios_base中,位於檔案xiosbase。不怕大家笑話,本菜從未見過operator void*這樣的過載,甚是不解。我只看過一本c++的教程,是譚浩強先生的《c++程式設計》,還是第一版。那本書當時我大概完整地看了有三四遍,記得書中沒有講過有關使用者自定義轉換的東西,也很久沒有再碰過那本書了,因為借給了同學……還是自己再找點東西吧。

首先,>>操作符返回的是流引用,所以才可以實現連續》的操作。>>和《都是從左至右結合,就是說譬如cin>>a>>b;這樣的語句,先結合cin>>a,輸入a之後返回流引用(就相當於是cin),繼續與後面的》b結合,就相當於是cin>>b,再次輸入b的值。

其次,ios_base還過載了void*。這種過載相當於是定義了一種轉換,由當前型別轉換到過載中宣告的型別。由其他型別轉換至當前型別很簡單,依靠建構函式就能解決;而從當前型別轉換至其他型別就需要靠這種過載來轉換,而且這種轉換可以銜接到標準轉換序列中。比如上述void*的轉換,返回的是乙個指標,指標的本質其實就相當於乙個ulong型別的變數,進而轉換至bool型別。所以,不論是while(cin)還是while(cin>>a)這樣的寫法,都可以得到正確的結果。

因此,使用者自定義轉換主要用於使用者自定義型別與其他型別(既包括內建型別也包括自定義型別)之間的相互轉換,可以分為兩大部分:從其他型別到當前型別的轉換;從當前型別到其他型別的轉換。前者主要是利用建構函式實現,後者主要靠過載轉換操作符來實現,而且過載函式沒有引數也沒有返回值。另外,這種轉換之後的型別只允許進入標準轉換序列。也就是說,如果在使用者自定義轉換之後仍需進行另一次使用者自定義轉換,編譯器將不會進行隱式轉換(也許我們用該要麼勤快一點,多寫一步顯示轉換;要麼一步到位,再過載乙個轉換操作符)。不過這種過載也可能造成二義性,也分兩種情況:

1.型別轉換序列中的二義性問題

這種二義性在標準轉換序列中就比較常見,比如float和int都可以經由標準序列轉換為long(沒有乙個是精確匹配),此時就是二義的;這種情況當然可能出現在我們的使用者自定義轉換當中。

2.兩種使用者自定義轉換之間的矛盾

假如有這樣乙個**,class a中由建構函式提供了從b到a的隱式轉換(通過建構函式);而在b中提供了由b到a的轉換(通過過載轉換操作符),那麼在轉換的時候到底應該應用哪乙個呢?此問編譯器不解,遂其罷工也……

解決方法是這樣的:一種方法為呼叫b.operator a()來顯示呼叫(有人說用a(b)也能達到目的,可以成功編譯。也許是c++標準和編譯器實現不同所致?),另一種方法為用explicit關鍵字顯示宣告a的建構函式,這樣a的建構函式將不再參與隱式轉換,也就消除了此類轉換的二義性。

通過自定義註解學到的

巨集觀上先確定思路,將思路分步驟以注釋形式寫出,開始不要考慮細節,將流程編寫出來 編譯無誤,執行檢查結果是否和自己心理預期的一樣。如果不一樣,再在現有 的基礎上修改,如果是未考慮到的條件,新增if判斷條件,debug直到和自己的預期為止。技術方面,當發現自己定義的變數要適應多種資料型別,如果這個變數...

C 自定義使用者控制項

上篇 控制項製作 本例是製作乙個簡單的自定義控制項,然後用乙個簡單的測試程式,對於初學者來說,本例子比較簡單,只能起到拋石引玉的效果。我也是在學習當中,今後會將自己所學的逐步寫出來和大家交流共享。第一步 新建乙個控制項庫專案 mycontrol 第二步 從工具箱裡面拖動1個picturebox 1個...

C 自定義使用者控制項

本例是製作乙個簡單的自定義控制項,然後用乙個簡單的測試程式,對於初學者來說,本例子比較簡單,只能起到拋石引玉的效果。我也是在學習當中,今後會將自己所學的逐步寫出來和大家交流共享。第一步 新建乙個控制項庫專案 mycontrol 第二步 從工具箱裡面拖動1個picturebox 1個button 6個...