條款27 盡量少做轉型動作

2021-07-03 13:31:57 字數 3324 閱讀 1093

在談及顯式轉換之前,先簡單說說隱式轉換。

int ival = 0;

ival = 3.541 + 3; //doubl向int轉換會丟失精度,編譯器會警告:「=」從double到int轉換可能會丟失資料,結果ival等於6

整數3被轉換為double型別,然後執行浮點型別加法操作,得double型別結果6.541,然後將double型別值賦值給int型別變數ival。在賦值中不可能改變左運算元的型別,因此左運算元型別佔主導地位。如果賦值操作的左右運算元型別不同,則右運算元會被轉換為左運算元的型別。本例中,double向int轉換自動按截尾形式進行,小數部分被捨棄,於是6.541變為6,然後賦給ival。

何時發生隱式型別轉換?

(1)在混合型別的表示式中

如上提到的例子那樣。

(2)用作條件的表示式被轉換為bool型別

int ival

if (ival) //ival轉換為bool

while (cin) //cin轉換為bool

條件操作符(?:)的第乙個表示式、邏輯非(!)、邏輯與(&&)、邏輯或(||)的運算元都是條件表示式;

出現在if、while、for和do while語句中的同樣都是條件表示式。

(3)用一表示式初始化某個變數或將一表示式賦值給某個變數,則該表示式被轉換為該變數的型別

int ival = 4.33;  轉換為int

int *p;

p = 0; //int的0轉為int *型別的null指標

算術轉換

算術轉換定義了乙個轉換層次,規定了運算元應該按什麼層次轉換為表示式章最寬的型別。轉換規則要確保計算值的精度。

例如整型提公升:對於所有比int小的整型,包括char、singed char、unsigned char、short、unsigned short,如果該型別所有可能值都包括在int內,它們都被提公升為int型,否則,它們會被提公升為unsigned int。如果將bool提公升為int,則false轉換為0,true轉換為1。

指標轉換

int ia[10];

int *p = ia; //將陣列自動轉換為指向第乙個元素的指標

指向任意型別的指標都可以轉換為void *型別;整數值常量0可轉換為任意指標型別。

轉換為const物件

使用非const物件初始化const物件的引用時,系統自動將非const物件轉換為const物件。還可以將非const物件的位址(或非const指標)轉換為指向相關const型別的指標:

int i;

const int ci = 0;

const int &j = i; // 將非const的i轉換為const int的引用

const int *p = &ci; //將ci的位址(非const)轉換為const位址

由標準庫型別定義的轉換

string s;

while (cin >> s)

隱式使用了io標準庫定義的型別轉換,求解表示式cin >> s,即讀入cin,無論讀入成功與否,該表示式結果都是cin,while迴圈條件應該為bool型別的值,而此時是istream型別值,於是其轉換為bool型別。

接著說顯式型別轉換:

(t) expression

t(expression)

兩種形式並無差別,僅僅是小括號的擺放位置不同而已。

去除表示式的常量性,是c++中唯一能去掉const屬性的轉型操作符,其他三種強制轉換運用於去除const都會導致編譯錯誤。類似地,除了新增或刪除const特性,將const_cast用於執行其他任何型別轉換,都會引起編譯錯誤。

用於強制隱式型別轉換,編譯器執行的任何型別的轉換都可以由static_cast顯示完成(除了將const轉換為非const)。

double d = 99.0;

char ch = static_cast(d);

當需要將乙個較大的算術型別賦值給較小的型別時,使用強制型別轉換很有用,此時強制型別告訴程式讀者和編譯器,我們知道並且不關心潛在的精度損失。如果隱式轉換,編譯器會警告,但是,這樣的顯式轉換時,警告資訊關閉。

如果編譯器不提供自動轉換,使用static_cast來執行轉換也很有用:

double d = 2.2;

void *p = &d;

double *dp = static_cast(p); //static_cast將存放在void*中的指標強制轉換為原來的指標型別。

static還可以將非const轉換為const物件、將int轉為double等;還能執行上述相反的轉換:將void* 轉為typed指標,將指向基類的指標轉為指向派生類的指標。

支援執行時識別指標或引用所指向的物件。主要用來執行「安全向下轉型」,也就是用來決定某個物件是否歸屬於繼承體系中某個型別。它將基類型別物件的引用或指標轉換為同一繼承層次中其他型別的引用或指標。

與dynamic_cast一起使用的指標必須是有效的——它必須為0或指向乙個物件。它是唯一無法由舊式語法執行的動作,也是唯一可能耗費重大執行成本的轉型動作。和其他強制型別轉換不同,它涉及執行時型別檢查。如果繫結到引用或指標的物件不是目標型別的物件,則dynamic_cast會失敗**換失敗時:如果是指標,結果為0;如果是引用,丟擲乙個bad_cast型別的異常)。

因此,dynamic_cast執行轉換前要先驗證轉換是否有效,只有轉換有效時,才進行轉換。

//

指標if (derived *derivedptr = dynamic_cast(baseptr)) else

//引用

void f(const base &b) catch (bad_cast)

}

文章c++多型

試圖執行低階轉型(例如將乙個指向整數變數的指標轉換為整數),實際動作及結果可能與編譯器相關,因而降低了可移植性。

第一,它們很容易在**中被識別出來;第二,各轉型動作的目標愈窄化,編譯器愈可能診斷出錯誤的運用。例如,打算去除const屬性,除非使用新式轉換const_cast,否則無法通過編譯。

未完成

條款27 盡量少做轉型動作

c 中的轉型語法包括舊式轉型和新式轉型。舊式轉換包括 t expression 將expression轉型為t,c風格的轉型動作 t expression 將expression轉型為t,函式風格的轉型動作 新式轉型包括 const cast expression const cast通常被用來將物...

條款27 盡量少做轉型動作

c 的設計目標之一是保證 型別錯誤 絕不會發生。但轉型 cast 破壞了型別系統 type system 舊式轉型,c風格的轉型動作,如下 t tmp 將tmp轉型為t t tmp 同上,函式風格的轉型動作 c 提供四種新式轉型 new style或c style casts 1 const cas...

條款27 盡量少做轉型動作

c 四種新式轉型 通常用來將物件的常量性轉除,將const轉成non const 用來執行 安全向下轉型 通過父類訪問子類 很少用到,忽略 用來強迫隱式轉換,例如將non const物件轉為const物件,或將int轉為double物件,也可以來執行上訴多種轉換的方向轉換,例如將void 指標轉為t...