C 中顯示型別轉換

2021-05-04 20:54:08 字數 2521 閱讀 1272

c++ 引入了 const_cast, reinterpret_cast 之類的新的顯式型別轉換方式,不僅大多數 c 程式設計師覺得不是很習慣,就連某些有經驗的c++ 程式設計師都會在一些細節上犯錯。誠然,既然我們可以簡單的寫出:

int i = (int)p;// p is a pointer

這樣的顯式轉換,為什麼還要使用

int i = reinterpret_cast( p );

這麼複雜的形式呢?

這篇文章的目的是簡單介紹 c++ 的型別轉換系統,並對使用和擴充套件進行一些討論。

1. 為什麼需要型別轉換?

型別轉換被用來把乙個型別的值轉換成另乙個型別。類似於 c++ 這樣的程式語言是強型別的,因此每乙個值都有它相應的型別。當你需要把乙個值轉換為另乙個型別時,你需要使用下列方式中的一種:隱式轉換,顯式轉換和無法轉換。假設我們使用老式的顯式轉換:

char c = 『a』;

int* p = null;

int a = c;// 隱式轉換

a=(int) p; // 顯式轉換

double d=(double) p;// 無法轉換

通常,隱式轉換意味著編譯器認為你的轉換是合理的或者是安全的;顯式轉換意味著編譯器能夠找到乙個轉換方式,但是它不保證這個轉換是否安全,所以需要程式設計師額外指出;而無法轉換則意味著編譯器無法發現一條直接的路徑來進行型別轉換。

2. 為什麼需要 c++ 風格的顯式轉換?

c++ 風格的顯式轉換為我們提供了更精確的語義和對其進一步擴充套件的可能。在 c 語言中,我們可以用乙個簡單的 (int*) 來完成下面的轉換:

const char* s = 0;

int* p = (int*) s;

這一句語句,不僅轉換了型別,還把 const 也去掉了。通常如果我們看到一句游離的顯式轉換,我們不能立即知道作者的意圖,這也為今後的錯誤埋下了伏筆。c++ 風格的現實轉換通過區分各種轉換情況來增加安全性:通過 const_cast 來取消 const、volatile 之類的修飾,通過 static_cast 來做相關型別的轉換,通過 reinterpret_cast 來做低階的轉換,...。有乙個例子可以說明這些轉換的「精確」程度:

class inte***ce;

class base {};

class derived : public inte***ce, public base {};

int main()

這段**中,兩個 cast 都是合法的,但是意義不同。前者意味著「把 b 的指標的值直接賦給 d1,並且把它作為 derived 型別解釋」,後者意味著「根據相關型別資訊來做轉換,如果可能,對 b 指標做一些偏移」。在上面這個例子裡面,d1 和 d2 是不相等的!可能由於很多書上都說:如果你要在指標之間互相轉換,應該使用 reinterpret_cast,所以不少程式設計師使用 reinterpret_cast 來做一切指標型別轉換,雖然通常他們不會得到錯誤,但是的確是不小的隱患。

3. 一些例子

(1) itf_cast

在 com 中,如果我有乙個指向 ihtmldocument 的介面指標,並且我想從中獲得乙個 ipersistfile 的指標,我們可以用下述**:

ipersistfile* ppersistfile;

if( failed( phtmldocument->queryinte***ce(iid_ipersistfile, (lpvoid*) &ppersistfile) ) )

throw something;

這段**很簡單但是不夠直接,所以我們可以實現這樣乙個函式:

template

t1 itf_cast(t2 v2)

然後我們可以把上面的語句寫成

ppersistfile = itf_cast( phtmldocument );

這非常的直觀。仔細的讀者可能會發現 __uuidof 不是標準的 c++ 所定義的,而是 vc 的乙個擴充套件。事實上,在這裡你可以用 traits 很簡單的實現同樣的功能。

(2) stream_cast

有時候,我們經常會 遇到一些自定義型別之間轉換問題,譬如說 std:string 和 double,甚至 std:string 和 rect 之類的轉換。如果參與轉換的兩個型別都定義了輸入輸出運算(精確的說,源型別支援輸出運算,目的型別支援輸入運算),那麼我們可以用以下的方式來進行轉換:

template

t1 stream_cast(const t2& v2)

這樣一來,你可以用以下語句進行轉換:

string s("0.5");

double d = stream_cast( s );

(3) safe_cast

有時候我們希望我們的顯式轉換是安全的,這裡安全的定義是,這個值在兩個型別中德表示都是無損的。也就是說,(t2)(t1)v1 == v1。那我們可以定義這樣的顯式轉換:

template

t1 stream_cast(const t2& v2)

於是,stream_cast(1000); 這樣的語句就會丟擲異常。

上面是我個人對於 c++ 風格的顯式型別轉換的一些理解和看法,希望有興趣的人一起討論。

C 顯示型別轉換

首先說明,該內容主要摘自c stl 開發技術導引。在c語言中,我們一般採用隱式型別轉換,這樣導致的結果是可讀性不高。如下這段 這段 將double型別轉換成了int型別,問題是如果別人來看這段 的時候,別人可能就不知道這種轉換是程式需要的還是編寫 的人不小心寫錯了呢。因此,在c 程式中應盡量使用顯示...

c 顯示型別轉換

dynamic cast,static cast,const cast,1.使用dynamic cast 操作符將基類型別物件的引用或者指標轉換為同一繼承層次中其他型別的引用或者指標 執行時型別檢查 2.const cast 操作符將變數的const性質轉換掉 example1 double d 8...

c 顯示型別轉換

c 引入了4個新的強制型別轉換操作符,static cast dynamic cast const cast reinterpret cast,用以支援更為精細的型別轉換。這些操作符取代了以往小圓括號所代表的舊式轉型,能夠清楚闡明轉型的目的。這些新式轉型操作符給了編譯器更多資訊,讓編譯器清楚知道轉型...