1. 程式人生 > >C++中的4個與型別轉換相關的關鍵字

C++中的4個與型別轉換相關的關鍵字

在C/C++語言中用 (type) value(在C++還可以採用type(value))來進行顯式型別轉換(explicit type conversion),常常又被稱為強制轉換(cast投射/鑄模)。這種轉換的正確性完全掌握在程式設計師手中,傳統上強制轉換往往被過度使用,成為C++程式犯錯的一個主要根源。
為了減少強制轉換的副作用,並且在查錯時使程式設計師能夠快速定位(總是最值得懷疑的)強制轉換,在標準C++中新增加了4個關鍵字*_cast,用來提倡一種全新的C++顯式轉換語法:
*_cast <type-id> (expression)

1.static_cast(靜態轉換):用於明確定義良性和適度良性的轉換,包括原來不需要採用強制轉換的自動型別轉換(包括無損的提升轉換和可能丟失資訊的窄化轉換[narrowing conversion],對後者編譯器一般會提出警告)。即將編譯器隱式執行的轉型弄成顯示的。標準C++提倡對任何資料的型別轉換(不論是自動的還是強制的),都採用新的*_cast顯式型別轉換方法。例如:

int i = 0x7fff;
long l;
float f;
char c;
// (1)典型的非強制轉換(自動轉換)
// 傳統方式:
l = i;
f = i;
// 提倡的新方式:
l = static_cast<long>(i);
f = static_cast<float>(i);
// (2)窄化轉換
// 傳統方式:
// 會顯示警告資訊:
i = l; // 可能丟失數字
i = f; // 可能丟失資訊
c = i; // 可能丟失數字
// 不顯示警告資訊(但仍然難定位):
i = (int)l;
i = (int)f;
c = (char)i;
// 提倡的新方式(不會顯示警告資訊,且易定位):
i = static_cast<int>(l);
i = static_cast<int>(f);
c = static_cast<char>(i); 2.const_cast(常量轉換):可將(同資料型別的)常型(const)轉換為非常型、將易變(volatile)型轉換為非易變型。如果用於其他型別的轉換,一般會產生一個編譯錯誤。例如:
const int i = 0;
int *pi;
pi = &i; // 錯誤
pi = (int *)&i; // 被反對
pi = const_cast<int *>(&i); // 完美
long *pl = const_cast<long *>(&i); // 錯誤
volatile int k = 0;
int *pk = const_cast<int *>(&k); // 正確

3.dynamic_cast(動態轉換):一種安全的向下型別轉換(downcast)操作,用於在一個類繼承層次上向下移動。

因為每個派生類的基類都只有一個,而且派生類本身又包含了幾乎所有的基類資訊(private型的除外),所以向上的型別轉換(upcast)總是唯一的和比較安全的。
而一個基類往往有多個派生類,而且派生類中一般會在基類的基礎上添加了一些特有的資料和操作,所以向下的型別轉換總是多型的和不太安全的。
dynamic_cast提供了一種安全的向下型別轉換操作,只有當型別轉換是正確的並且轉換取的成功,返回值才是所需要的指標;否則它將返回0(空指標NULL),表示不是正確的型別。
例如:
class Pet {……};
class Dog : public Pet {……};
class Cat : public Pet {……};
……
Pet *pPet = new Cat; // 向上的型別轉換
Dog *pDog = dynamic_cast<Dog *>(pPet); // 型別錯誤,返回0(NULL)
Cat *pCat = dynamic_cast<Cat *>(pPet); // 型別正確,返回指標
Cat *pCat = static_cast<Cat *>(pPet); // 正確,減少執行時的開銷

注意:dynamic_cast雖然安全,但是執行時需要一定開銷,因此不提倡大量使用這種轉換。如果你已經能夠確認轉換的正確性,則可以採用前面介紹過的(無執行時開銷的)static_cast轉換。只有當你實在無法確定轉換是否正確時,才需要採用dynamic_cast轉換。

4.reinterpret_cast(重解釋轉換):一種最有可能出問題的最不安全的型別轉換。只是在下面的情形,才需要使用這種型別轉換:當需要使用時,所得到的東西已經不同了,為了使它能夠用於原來的目的,必須再次把它轉換回來。例如:
const int sz = 100; // 定義陣列大小,標準C++提倡用常型變數(而不是常數或
// 符號常量巨集)
struct X {int a[sz];}; // 只包含一個整數陣列的結構
X x; // 定義結構變數,此時結構中的陣列元素的值無意義(需要初始化)
int *px = reinterpret_cast<int *> (&x); // 為了初始化,先把結構轉化為int陣列
for (int *i = px; i < px + sz; i++) *i = 0; // 將每個陣列元素的值初始化為0
print(reinterpret_cast<X *> (px)); // 重新轉換成結構指標,以便使用
// 也可以直接使用原來的識別符號x
// 此語句相當於print(&x);
使用reinterpret_cast通常是一種不明智且不方便的程式設計方式。但是在必須使用時,它也是非常有用的。
 

在這四種強制轉換中,static_cast最常用(目前還沒有流行起來,但是被標準C++著力提倡)、dynamic_cast最重要、const_cast也有用、而reinterpret_cast則很少被使用。 

(文章出處:http://blog.csdn.net/touzani/article/details/1637655)

相關推薦

C++4型別轉換相關關鍵字

static_cast const_cast dynamic_cast reinterpret_cast 一.型別轉換     表示式是否合法取決於運算元的型別,而且合法的表示式其含義也由運算元型別決定。在C++中,某些型別之間存在相

C++4型別轉換相關關鍵字

在C/C++語言中用 (type) value(在C++還可以採用type(value))來進行顯式型別轉換(explicit type conversion),常常又被稱為強制轉換(cast投射/鑄模)。這種轉換的正確性完全掌握在程式設計師手中,傳統上強制轉換往往被過度使

c++,有哪4型別轉換相關關鍵字,這些關鍵字各有什麼特點,應該在什麼場合下使用?

1、reinterpret_cast<type-id> (expression) type-id 必須是一個指標、引用、算術型別、函式指標或者成員指標。它可以把一個指標轉換成一個整數,也可以把一個整數轉換成一個指標(先把一個指標轉換成一個整數,再把該整數轉換成原型別的指標,還可以得到原先的指標值

C++,有哪4型別轉換相關關鍵字?這些關鍵字各有什麼特點,在什麼場合下使用?

1 reinterpret_cast ‘reinterpret_cast’轉換一個指標為其它型別的指標。它也允許從一個指標轉換為整數型別。反之亦然。(譯註:是指標具體的地址值作為整數值?) 這個操作符能夠在非相關的型別之間轉換。操作結果只是簡單的從一個指標到

C++,有哪四型別轉換相關關鍵字

C++與型別轉換相關的四個關鍵字有:const_cast, static_cast, dynamic_cast, reinterpret_cast static_cast——運算子完成相關型別之間的轉換 【特點】:靜態轉換,在編譯處理期間。 【應用場合

C++型別轉換相關4關鍵字

轉自http://blog.csdn.net/xmu_jupiter/article/details/42456307 首先,C++與型別轉換相關的四個關鍵字有:const_cast, static_cast, dynamic_cast, reinterpret_cas

C++型別轉換相關的四關鍵字及其特點

首先,C++與型別轉換相關的四個關鍵字有:const_cast, static_cast, dynamic_cast, reinterpret_cast. 什麼是型別轉換? 表示式是否合法取決於運算元的型別,而且合法的表示式其含義也由運算元型別決定。但是在C++中,某

C#4訪問修飾符(隨筆)

結構 public 成員訪問 集中 internal pub ted 限制 nal Public:公有的,是類型和類型成員的訪問修飾符。對其訪問沒有限制。 Internal:內部的,是類型和類型成員的訪問修飾符。同一個程序集中的所有類都可以訪問 Private:私

C#程式設計基礎第十課:C#的常用資料型別轉換:隱式轉換、顯式轉換、Convert類轉換

知識點:型別轉換、數值型別間的轉換、隱式型別轉換、顯式型別轉換、數值型別和string型別的轉換、Convert類轉換。 1、資料型別型別轉換 理解:從根本上說是型別鑄造,或者說是把資料從一種型別轉換為另一種型別。C#有多種資料型別,在使用各種型別的資料時,有時候需要將一種型別的資料轉換

c#4訪問修飾符和8宣告修飾符詳解

[1]In GrandClass.Constructor [2]In ParentClass.Constructor [3]In ParentClass.Method() use override [4]In GrandClass.Constructor [5]In NewParentClass.Constr

C/C++基礎----過載運算型別轉換

非成員版本 data1 + data2; operator+(data1, data2); 成員版本 data1 += data2; data1.operator+=(data2); 不建議的過載 邏輯與、邏輯或、逗號的運算物件求值順序規則無法保留。 &&和||的過載版本也

CC++的字串數字轉換函式

前言:       今天開始想要好好補補程式,開始看老早就買了的《演算法入門經典》,發現前面幾章對字串的處理較多,蒐羅了一下別人的部落格,整理到這上面來。        C語言中常用的字串和數字轉換函

c++四種強制型別轉換(const_cast、static_cast應用最多)

c++動態型別轉換有四種const_cast、static_cast、dynamic_cast、reinterpreter_cast 前面兩個用的多,但是後面的針對其設計理念有許多其他的實現方法可達到同樣的效果 1. static_cast (1)用於基

c++比較不常用的關鍵字

我們在編寫應用程式的時候explicit關鍵字基本上是很少使用,它的作用是"禁止單引數建構函式"被用於自動型別轉換,其中比較典型的例子就是容器型別,在這種型別的建構函式中你可以將初始長度作為引數傳遞給建構函式.例如:你可以宣告這樣一個建構函式class Array{public: explicit Array

【面試題】c++有哪四型別轉換相關關鍵字

在C/C++語言中用 (type) value(在C++還可以採用type(value))來進行顯式型別轉換(explicit type conversion),常常又被稱為強制轉換(cast投射/鑄模)。這種轉換的正確性完全掌握在程式設計師手中,傳統上強制轉換往往被過度使

c++ primer 第十四章過載運算型別轉換

c++ primer 第十四章過載運算與型別轉換 14.1 基本概念 14.2 輸入和輸出運算子 14.2.1 過載輸出運算子<< 14.2.2 過載輸入運算子>> 14.3 算術

詳解C++基類派生類的轉換以及虛基類

原文來源:https://www.jb51.net/article/72586.htm# C++基類與派生類的轉換 在公用繼承、私有繼承和保護繼承中,只有公用繼承能較好地保留基類的特徵,它保留了除建構函式和解構函式以外的基類所有成員,基類的公用或保護成員的訪問許可權在派生類中全部都按原樣保留下來

C#結構體位元組流互相轉換

C++的訊息結構體如下 struct cs_message{ u32_t cmd_type; char username[16]; u32_t dstID; u32_t

C++std::stringC-String字元陣列的互相轉換

C語言中只有字元陣列這一說法,沒有C++專門封裝的字串類std::string。而字元陣列C-String以\0作為結束符。std::string其實還是儲存了C-String這個指標,只不過不同的編譯期對std::string中的儲存結構都做了不同的處理,這裡我們不討論std::str

C++數值字元字串的相互轉換

C++處理字串和數值時,經常需要相互轉換。C++11及以上的<string>就提供了很多類似的函式。 字串轉化為數值 Convert from strings stoi    Convert string to integer