C 高階篇(四) 型別轉換高階

2021-08-26 12:16:59 字數 3321 閱讀 9526

目前為止,我們一直使用傳統的型別轉換符來進行簡單物件的型別轉換。例如,要把乙個double型別的浮點型數字轉換為int 的整型數字,我們是這樣做的:

int i;

double d;

i = (int) d;或者

i = int (d);

這樣做對基本資料型別時沒問題的,因為基本資料型別的轉換已經有標準的定義。同樣的操作也可以被在類或類的指標上,因此以下例子中的寫法也是沒有問題的:

// class type-casting

#include class cdummy ;

class caddition

int result()

};int main ()

雖然以上程式在c++中是沒有語法錯誤的(多數編譯器甚至不會產生警告資訊),但這段程式沒有什麼實際的邏輯意義。我們使用了caddition 的成員函式result 而沒有定義乙個相應的該類的物件:padd 並不是乙個物件,它只是乙個指標,被我們賦值指向乙個毫無關係的物件的位址。當在程式執行到訪問它的result 成員函式時,將會有乙個執行錯誤(run-time error)產生,或生成乙個意外的結果。

為了控制這種類之間的轉換,ansi-c++ 標準定義了4種新的型別轉換操作符: reinterpret_cast, static_cast, dynamic_cast 和 const_cast。所有這些操作符都是同樣的使用格式:

reinterpret_cast (expression)

dynamic_cast (expression)

static_cast (expression)

const_cast (expression)

這裡new_type 是要轉換成的目標型別,expression 是要被轉換的內容。為了便於理解,模仿傳統轉換操作符,它們的含義是這樣的:

(new_type) expression

new_type (expression)

reinterpret_cast 可以將乙個指標轉換為任意其它型別的指標。它也可以用來將乙個指標轉換為乙個整型,或反之亦然。

這個操作符可以在互不相關的類之間進行指標轉換,操作的結果是簡單的將乙個指標的二進位制資料(binary copy)複製到另乙個指標。對指標指向的內容不做任何檢查或轉換。

如果這種複製發生在乙個指標到乙個整數之間,則對其內容的解釋取決於不同的系統,因此任何實現都是不可移植(non portable)的。乙個指標如果被轉換為乙個能夠完全儲存它的足夠大的整數中,則是可以再被轉換回來成為指標的。

例如:class a {};

class b {};

a * a = new a;

b * b = reinterpret_cast(a);

reinterpret_cast 對所有指標的處理與傳統的型別轉換符所作的一模一樣。

static_cast 可以執行所有能夠隱含執行的型別轉換,以及它們的反向操作(即使這種方向操作是不允許隱含執行的)。

用於類的指標,也就是說,它允許將乙個引申類的指標轉換為其基類型別(這是可以被隱含執行的有效轉換),同時也允許進行相反的轉換:將乙個基類轉換為乙個引申類型別。

在後面一種情況中,不會檢查被轉換的基類是否真正完全是目標型別的。例如下面的**是合法的:

class base {};

class derived: public base {};

base * a = new base;

derived * b = static_cast(a);

static_cast除了能夠對類指標進行操作,還可以被用來進行類中明確定義的轉換,以及對基本型別的標準轉換:

double d=3.14159265;

int i = static_cast(d);

譯者注:如果你對這部分看不太懂,請結合下面的dynamic_cast一起看,也許會幫助理解。

dynamic_cast 完全被用來進行指標的操作。它可以用來進行任何可以隱含進行的轉換操作以及它們被用於多型類情況下的方向操作。然而與static_cast不同的是, dynamic_cast 會檢查後一種情況的操作是否合法,也就是說它會檢查型別轉換操作是否會返回乙個被要求型別的有效的完整的物件。

這種檢查是在程式執行過程中進行的。如果被轉換的指標所指向的物件不是乙個被要求型別的有效完整的物件,返回值將會是乙個空指標null 。

class base ; };

class derived : public base ;

base* b1 = new derived;

base* b2 = new base;

derived* d1 = dynamic_cast(b1); // succeeds

derived* d2 = dynamic_cast(b2); // fails: returns null

如果型別轉換被用在引用(reference)型別上,而這個轉換不可能進行的話,乙個bad_cast 型別的例外(exception)將會被丟擲:

class base ; };

class derived : public base ;

base* b1 = new derived;

base* b2 = new base;

derived d1 = dynamic_cast(b1); // succeeds

derived d2 = dynamic_cast(b2); // fails: exception thrown

這種型別轉換對常量const 進行設定或取消操作:

class c {};

const c * a = new c;

c * b = const_cast(a);

其他3種cast 操作符都不可以修改乙個物件的常量屬性(constness)。

ansi-c++ 還定義了乙個新的操作符叫做 typeid ,它檢查乙個表示式的型別:

typeid (expression)

這個操作符返回乙個型別為type_info的常量物件指標,這種型別定義在標準頭函式中。這種返回值可以用操作符 == 和 != 來互相進行比較,也可以用來通過name()函式獲得乙個描述資料型別或類名稱的字串,例如:

// typeid, typeinfo

#include #include class cdummy ;

int main ()

return 0;

}

a and b are of different types:

a is: class cdummy *

b is: class cdummy

四 型別轉換

型別之間的轉換 c 語言中的資料型別可以進行轉換 強制型別轉換 強制型別轉換的語法 type var name type value 強制型別轉換的結果 目標型別能夠容納目標值 結果不變 目標型別不能容納目標值 結果將產生截斷 注意 不是所有的強制型別轉換都能成功,當不能進行強制型別轉換時,編譯器將...

C 高階 07 型別轉換

型別轉換就目前 get 到的在 c 裡面一共有兩種,隱式轉換跟顯式轉換 也叫強勢轉換 下面咱們乙個乙個的以 例項來介紹。1,隱式轉換 參與運算 算術運算和賦值運算 的運算元和結果型別必須一致,當不一致時,滿足下面條件時系統自動完成型別轉換 隱式轉換 1 兩種型別相容 例如 int 和 double ...

C語言高階剖析 4 型別轉換

c語言中的資料型別可以轉換,分為強制型別轉換和隱式型別轉換 int main 注意 不是所有的強制型別轉換都能成功,當不能進行強制型別轉換時,編譯器將產生錯誤資訊 舉例說明 這是編譯器主動進行的型別轉換 注意 低型別到高型別的隱式型別轉換是安全的,不會產生截斷 高型別到低型別的隱式型別轉換是不安全的...