C中的型別轉換:
事情要從頭說起,這個頭就是C語言.我們已經習慣了使用C-like型別轉換,因為它強大而且簡單.
主要有一下兩種形式:
(new-type) expression
new-type ( expression)
C風格的轉換格式很簡單,但是有不少缺點:
1.轉換太過隨意,可以在任意型別之間轉換。你可以把一個指向const物件的指針轉換成指向非const物件的指針,把一個指向基底類別物件的指針轉換成一個派生類別物件的指針,這些轉換之間的差距是非常巨大的,但是傳統的C語言風格的類型轉換沒有區分這些。
2.C風格的轉換沒有統一的關鍵字和標示符。對於大型系統,做程式碼排查時容易遺漏和忽略。
C 中的型別轉換:
C 風格完美的解決了上面兩個問題。 1.對類型轉換做了細分,提供了四種不同類型轉換,以支援不同需求的轉換;2.類型轉換有了統一的標示符,利於程式碼排查和檢視。以下分別來介紹這四個轉換:static_cast、dynamic_cast、const_cast和reinterpreter_cast.
static_cast,命名上理解是靜態型別轉換。如int轉換成char。
dynamic_cast,命名上理解是動態型別轉換。如子類別和父類別之間的多型別轉換。
const_cast,字面上理解就是去const屬性。
reinterpreter_cast,僅重新解釋類型,但沒有進行二進位的轉換。
一、static_cast轉換
1.基本用法:static_cast expression
2.使用場景:
a、用於類別層次結構中基類別和衍生類別之間指標或引用的轉換
上行轉換(衍生類別—->基類別)是安全的;
下行轉換(基底類別—->派生類別)由於沒有動態類型檢查,所以是不安全的。
b、用於基本資料型別之間的轉換,如把int轉換成char,這種帶來安全性問題由程式設計師來保證
c、把空指標轉換成目標類型的空指標
d、把任何型別的運算式轉換成void型別
3.使用特點
# a、主要執行非多態的轉換操作,用於取代C中通常的轉換操作
b、隱式轉換都建議使用static_cast進行標明和替換
int n = 6;double d = static_cast<double>(n); // 基本类型转换int *pn = &n;double *d = static_cast<double *>(&n) //无关类型指针转换,编译错误void *p = static_cast<void *>(pn); //任意类型转换成void类型
二、dynamic_cast轉換
1.基本用法:dynamic_cast expression
2.使用場景:只有在派生類別之間轉換時才使用dynamic_cast,type -id必須是類別指針,類別引用或void*。
3.使用特點:
a、基類必須要有虛函數,因為dynamic_cast是運行時類型檢查,需要運行時類型信息,而這個信息是儲存在類別的虛擬函數表中,只有一個類別定義了虛函數,才會有虛函數表(如果一個類別沒有虛函數,那麼一般意義上,這個類別的設計者也不想它成為一個基底類別) 。
b、對於下行轉換,dynamic_cast是安全的(當類型不一致時,轉換過來的是空指針),而static_cast是不安全的(當類型不一致時,轉換過來的是錯誤意義的指針,可能造成踩內存,非法訪問等各種問題)
c、dynamic_cast還可以進行交叉轉換
class BaseClass {public: int m_iNum; virtual void foo(){};//基类必须有虚函数。保持多台特性才能使用dynamic_cast};class DerivedClass: public BaseClass {public: char *m_szName[100]; void bar(){}; }; BaseClass* pb = new DerivedClass(); DerivedClass *pd1 = static_cast<DerivedClass *>(pb);//子类->父类,静态类型转换,正确但不推荐DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb);//子类->父类,动态类型转换,正确BaseClass* pb2 = new BaseClass();//父类->子类,静态类型转换,危险!访问子类m_szName成员越界DerivedClass *pd21 = static_cast<DerivedClass *>(pb2);//父类->子类,动态类型转换,安全的。结果是NULLDerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2);
#三、const_cast轉換
1.基本用法
:const_castexpression2.使用場景
:a、常數指針轉換為非常量指針,並且仍然指向原來的物件
b、常數引用被轉換為非常量引用,並且仍然指向原來的物件3.使用特點
: a、cosnt_cast是四種型別轉換符中唯一可以對常數進行操作的轉換符號 b、移除常數性是一個危險的動作,盡量避免使用。一個特定的場景是:類別透過const提供重載時,一般都是非常量函數呼叫const_cast將參數轉換為常數,然後呼叫常數函數,然後得到結果再呼叫const_cast 去除常數性。struct SA { int i; };const SA ra;//ra.i = 10; //直接修改const类型,编译错误SA &rb = const_cast<SA&>(ra); rb.i = 10;
int doSomething(){return 0;};//FuncPtr is 一个指向函数的指针,该函数没有参数,返回值类型为 voidtypedef void(*FuncPtr)();//10个FuncPtrs指针的数组 让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存//入funcPtrArray数组:FuncPtr funcPtrArray[10]; funcPtrArray[0] = &doSomething;// 编译错误!类型不匹配,reinterpret_cast可以让编译器以你的方法去看待它们:funcPtrArrayfuncPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething);//不同函数指针类型之间进行转换
总结:
去const属性用const_cast。
基本类型转换用static_cast。
多态类之间的类型转换用daynamic_cast。
不同类型的指针类型转换用reinterpreter_cast。
相关文章:
相关视频:
以上是C++中的四種強制型別轉換_基本用法及使用場景的詳細內容。更多資訊請關注PHP中文網其他相關文章!