首頁  >  文章  >  後端開發  >  C++中的四種強制型別轉換_基本用法及使用場景

C++中的四種強制型別轉換_基本用法及使用場景

php是最好的语言
php是最好的语言原創
2018-08-01 14:20:393566瀏覽

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_castexpression

  2.使用場景

  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;

###四、reinterpret_cast轉換#########  1.###基本用法###:reinterpret_castexpression######  2.###使用場景### #:不到萬不得已,不用使用這個轉換符,高風險操作######  3.###使用特點###:  ######  a、reinterpret_cast是從底層對資料重新解釋,依賴具體的平台,可移植性差######  b、reinterpret_cast可以將整型轉換為指針,也可以把指針轉換為數組######  c、reinterpret_cast可以在指針和引用裡進行肆無忌憚的轉換###
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++ 的强制类型转换

【c#教程】C# 类型转换

相关视频:

PHP数据类型转换之自动类型转换

以上是C++中的四種強制型別轉換_基本用法及使用場景的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn