在c中我們知道資料型別之間會進行隱式的型別安全轉換,轉換規則為小型別轉大型別。
下面看一些隱式轉換的例子:
short s = 'a';//合法
unsigned int ui = 200;//合法
int i = -1000;//合法
double d = i;//合法
上面語句都是合法的,要麼同型別賦值,要麼小型別往大型別賦值,當我們在進行資料型別運算時就要注意型別之間的隱式轉換了。
if( (ui + i) > 0 )
cout << "(ui +i) > 0" << endl;
else
cout << "(ui +i) < 0" << endl;
這會輸出(ui + i) < 0的語句,因為發生了型別轉換,將i的型別提公升到了unsigned int 了,所以兩個數相加結果將是乙個巨大的正數。
cout << "sizeof(s + 'b') = " << sizeof(s + 'b') << endl;
輸出什麼?將short型別和char型別相加後求型別長度,答案會是2嗎?不是,由於編譯器在計算int型別是最高效的,因為對於32位機子一次取32bit是最快的,也就是4位元組,當編譯器遇到乙個short和乙個char時就會先考慮將他們都轉為int再進行運算
所以答案是4.
了解了普通型別之間的轉換後來思考一下普通型別和類型別之間能發生轉換嗎?
定義乙個test類,裡面有乙個私有成員變數,乙個無參建構函式和乙個普通成員函式。
class test
};
執行下面語句:
test t;
t = 5;
怎麼樣?能行嗎?當然不行,編譯器會報錯,說兩個運算元之間無法匹配。
此時是否就會想到通過直接呼叫建構函式生成乙個臨時物件後賦值給test物件t。
那麼我們加乙個帶參建構函式試試:
test(int i)
再執行上面語句就能通過編譯了,為什麼?
因為類裡面有一種函式叫做轉換建構函式,它本質還是建構函式,在需要進行隱式型別轉換時呼叫,它滿足只有乙個引數,引數型別是普通型別或者是其他類型別(就是引數型別不能是自身型別)。
當有這個轉換建構函式存在後,執行t = 5;時,由於在老舊的c版本中存在類似i = int(5);的行為,類似的,當直接對類物件進行賦值(該值不為當前類型別)時,編譯器會查詢當前類裡面是否存在轉換建構函式,如果存在,t = 5;就將隱式轉成t = test(5);然後呼叫建構函式,這是由於編譯器會盡力幫你讓原始碼通過編譯,但這也不一定就是好事。
現在我們進行乙個+操作符的過載:
test operator + (const test& p)
執行這幾條語句:
test t;
t = 5;
test r;
r = t + 10;
cout << r.value() << endl;
直接看結果吧,首先編譯通過是肯定的,然後cout的結果是15,好像也沒什麼不對,結果就應該是15,為什麼是15?因為對+操作符過載後可以在類型別之間進行+操作,編譯器會將10隱式轉換成test(10),所以結果就為15.但是,r = t + 10;語句如果是我誤操作方法是有的,通過explicit關鍵字就可以拒絕編譯器嘗試進行隱式轉換,當轉換建構函式通過explicit關鍵字修飾後就只能進行顯式轉換。
static_cast (value);---->static_cast (10);或者test(10);但是不推薦使用(test)10;
C 學習筆記 建構函式與隱式轉換
程式設計課時老師給出了關於建構函式與型別隱式轉換的乙個例子 設對以下複數類 include using namespace std class complex complex operator const complex other intget real intget imag private i...
C 學習筆記 建構函式
在建立某個類的物件時,由於對該物件的狀態 資料 不很明確,因此需要對其進行初始化。例如,我們要在長方形中建立乙個物件,或者說新建乙個長方形,那麼我們首先要確定它的長和寬,假如我們無法確定它的長和寬,那麼我們是無法構造出乙個長方形來的。例如,我們要構造乙個長方形,由於建構函式要在建立新物件時使用,因此...
C 轉換建構函式和轉換函式
1 轉換建構函式的作用 作用 將某種型別轉換為類型別 例如有下面的 base int a 轉換建構函式 base b 物件 b 12 解析 程式將使用建構函式base int a 構造出乙個臨時的無名base物件,並用12對其初始化。然後採用逐個成員賦值的方式將該臨時物件的內容賦值給物件b。這一過程...