標準C+的類型轉換符:static_cast等

2021-01-10 騰訊網

一、 強制轉型

1) C 風格(C-style)強制轉型:

(T) exdivssion // cast exdivssion to be of type T

2) 函數風格(Function-style)強制轉型使用這樣的語法:

T(exdivssion) // cast exdivssion to be of type T

上面兩種形式之間沒有本質上的不同,它純粹就是一個把括號放在哪的問題,我們把這兩種形式稱為舊風格(old-style)的強制轉型。

二、 C++類型轉換

使用標準C++的類型轉換符,主要有四種類型: static_cast、dynamic_cast、reinterdivt_cast 、 const_cast

1 static_cast

用法:static_cast( exdivssion )

該運算符把exdivssion轉換為type-id類型,但沒有運行時類型檢查來保證轉換的安全性。它主要有如下幾種用法:

用於類層次結構中基類和子類之間指針或引用的轉換。

進行上行轉換(把子類的指針或引用轉換成基類表示)是安全的;

進行下行轉換(把基類指針或引用轉換成子類表示)時,由於沒有動態類型檢查,所以是不安全的。

用於基本數據類型之間的轉換,如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。

把空指針轉換成目標類型的空指針。

把任何類型的表達式轉換成void類型。

注意:static_cast不能轉換掉exdivssion的const、volitale、或者__unaligned屬性。

2 dynamic_cast

用法:dynamic_cast( exdivssion )

該運算符把exdivssion轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void *;

如果type-id是類指針類型,那麼exdivssion也必須是一個指針,如果type-id是一個引用,那麼exdivssion也必須是一個引用。

dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。

在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;

在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。

class B{

public:

int m_iNum;

virtual void foo();

};

class D:public B{

public:

char *m_szName[100];

};

void func(B *pb){

D *pd1 = static_cast(pb);

D *pd2 = dynamic_cast(pb);

}

在上面的代碼段中,如果pb指向一個D類型的對象,pd1和pd2是一樣的,並且對這兩個指針執行D類型的任何操作都是安全的;

但是,如果pb指向的是一個B類型的對象,那麼pd1將是一個指向該對象的指針,對它進行D類型的操作將是不安全的(如訪問m_szName),

而pd2將是一個空指針。

另外要注意:B要有虛函數,否則會編譯出錯; static_cast 則沒有這個限制。

這是由於運行時類型檢查需要運行時類型信息,而這個信息存儲在類的虛函數表(

關於虛函數表的概念,詳細可見)中,只有定義了虛函數的類才有虛函數表,

沒有定義虛函數的類是沒有虛函數表的。

另外,dynamic_cast還支持交叉轉換(cross cast)。如下代碼所示。

class A{

public:

int m_iNum;

virtual void f(){}

};

class B:public A{

};

class D:public A{

};

void foo(){

B *pb = new B;

pb->m_iNum = 100;

D *pd1 = static_cast(pb); //compile error

D *pd2 = dynamic_cast(pb); //pd2 is NULL

delete pb;

}

在函數foo中,使用static_cast進行轉換是不被允許的,將在編譯時出錯;而使用 dynamic_cast的轉換則是允許的,結果是空指針。

3 reindivter_cast

用法:reindivter_cast (exdivssion)

type-id必須是一個指針、引用、算術類型、函數指針或者成員指針。

它可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,

在把該整數轉換成原類型的指針,還可以得到原先的指針值)。

該運算符的用法比較多。

4 const_cast

用法:const_cast (exdivssion)

該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾之外, type_id和exdivssion的類型是一樣的。

常量指針被轉化成非常量指針,並且仍然指向原來的對象;

常量引用被轉換成非常量引用,並且仍然指向原來的對象;常量對象被轉換成非常量對象。

Voiatile和const類試。舉如下一例:

class B{

public:

int m_iNum;

}

void foo(){

const B b1;

b1.m_iNum = 100; //comile error

B b2 = const_cast(b1);

b2. m_iNum = 200; //fine

}

上面的代碼編譯時會報錯,因為b1是一個常量對象,不能對它進行改變;

使用const_cast把它轉換成一個常量對象,就可以對它的數據成員任意改變。注意:b1和b2是兩個不同的對象。

三、 轉換類型比較 (dynamic_cast VS static_cast )

class B { ... };

class D : public B { ... };

void f(B* pb)

{

D* pd1 = dynamic_cast (pb);

D* pd2 = static_cast

(pb);

}

相關焦點

  • C++開發必看 四種強制類型轉換的總結
    【IT168 技術】C風格的強制類型轉換(Type Cast)很簡單,不管什麼類型的轉換統統是:  C++風格的類型轉換提供了4種類型轉換操作符來應對不同場合的應用。  const_cast,字面上理解就是去const屬性。  static_cast,命名上理解是靜態類型轉換。
  • 誰說C++ 的強制類型轉換很難懂?
    static_cast在C++中,staticcast相當於C語言中的強制類型轉換語法。staticcast用於在編譯期對某種類型的變量進行強制類型轉換。參考以下代碼:intmain(){static_cast<int *>(malloc(0));static_cast<int>(0.);}上述代碼中,我們使用了static_cast分別將void *轉為了int *,以及將double轉為了int。
  • C++的轉換手段並與explicit關鍵詞配合使用
    reinterpret_cast,僅僅重新解釋類型,但沒有進行二進位的轉換。static_cast:任何具有明確定義的類型轉化,只要不包含底層const,都可以使用static_cast,舉一個例子。static_cast<double*>(&p) //將void*轉化為初始的指針類型static_cast強制轉換隻會在編譯時檢查,但沒有運行時類型檢查來保證轉換的安全性。
  • 十分鐘理解C ++中的運算符重載
    在C ++中,我們可以使運算符為用戶定義的類工作。這意味著C ++能夠為運算符提供數據類型的特殊含義,這種能力稱為運算符重載。real + c2.關於運算符重載的要點1)為了使運算符重載起作用,至少一個操作數必須是用戶定義的類對象。2) 賦值運算符:編譯器會自動為每個類創建一個默認的賦值運算符。默認賦值運算符確實將右側的所有成員分配到左側,並且在大多數情況下都可以正常工作(此行為與複製構造函數相同)。請參閱此了解更多詳情。
  • java修飾符
    聲明為私有訪問類型的變量只能通過類中公共的 getter 方法被外部類訪問。Private 訪問修飾符的使用主要用來隱藏類的實現細節和保護類的數據。非訪問修飾符為了實現一些其他的功能,Java 也提供了許多非訪問修飾符。static 修飾符,用來修飾類方法和類變量。final 修飾符,用來修飾類、方法和變量,final 修飾的類不能夠被繼承,修飾的方法不能被繼承類重新定義,修飾的變量為常量,是不可修改的。abstract 修飾符,用來創建抽象類和抽象方法。
  • 引用數據類型的概念_引用數據類型有哪幾種
    *   * 翻譯:Void類是一個不可重複的佔位符類,   * 用於保存對表示Java關鍵字void的Class對象的引用   **/   public final class Void { //final表明這個類是不允許被其他類繼承   /**   * The Class object representing
  • C+基礎知識篇:C+存儲類
    這些說明符放置在它們所修飾的類型之前。 auto 存儲類 自 C++ 11 以來,auto關鍵字用於兩種情況:聲明變量時根據初始化表達式自動推斷該變量的類型、聲明函數時函數返回值的佔位符。 C++98標準中auto關鍵字用於自動變量的聲明,但由於使用極少且多餘,在C++11中已刪除這一用法。
  • Java之static靜態關鍵字詳解
    前言在Java語言中,static表示「靜態」的意思,使用場景可以用來修飾成員變量和成員方法,當然也可以是靜態代碼塊。static的主要作用在於創建獨立於具體對象的域變量或者方法。本文主要來去講解一下static的來龍去脈。static要解決什麼問題?
  • 「Java」基礎19:修飾符有哪些?
    這就得學到一個新的修飾符了。一、final修飾符final,翻譯成中文就是「不可更改的 」。顧名思義,它是一個修飾符,用於修改不可更改的內容。被final修飾的類:不能被繼承。被final修飾的方法:不能被重寫。被final修飾的變量:不能被重新賦值。被final修飾的常量:名稱一般都有書寫規範,所有字母都大寫。
  • Unity - Raycast 射線檢測
    光線投射碰撞信息Raycast 光線投射SphereCast 球體投射OverlapSphere 相交球等項目地址:Raycast - SouthBegonia (https://github.com/SouthBegonia/UnityWorld/tree/master/Raycast)
  • 如何用Bull轉換任意類型的Java Bean
    } }但是,我們可以將庫配置為為欄位類型分配默認值(如:0為int類型,null為String等等)ToBean toBean = new BeanUtils().getTransformer().setDefaultValueForMissingField
  • 最全的C語言基礎知識都在這了
    儘管C語言提供了許多低級處理的功能,但仍然保持著跨平臺的特性,以一個標準規格寫出的C語言程序可在包括一些類似合法標識符如下:A6, b_3 , _mn非法的標識符如下:ab#12 , 8m , tr3:4 , yes no標識符不能與程序中具有特殊意義的關鍵字相同,不能與用戶編制的函數名、C語言庫函數相同,在程序中各種標識符儘量不要重複
  • C#核心開發-類型之間可強制轉換,Convert.Toxxx()如何強制轉換?
    C#核心開發-第4單元-運算符和表達式-第10節:強制轉換一都編程-C#核心開發強制轉換在C#中,強制轉換使用的比較多,並且還可以跨數據類型轉換,甚至可以在值類型和引用類型之間轉換。強制類型轉換需要藉助於工具,不能直接使用賦值號實現轉換。常用的C#強制轉換工具有:Convert.Toxxx()方法、()、ToString()、Parse()等。1.
  • 2003年10月甘肅省高等教育自學考試C語言程序設計試卷
    =D〈=  15.以下關於typedef的敘述中錯誤的是 ()  A用typedef可以增加新的類型  B用typedef可以定義各種類型名,但不能用來定義變量  C用typedef只是將已有的類型用新的標識符來代表  D使用typedef有利於程序的通用和移植  16.若執行完成下列語句:  int
  • C語言基礎知識學習(一)
    標識符分類a) 關鍵字原先的C89標準中只有32個關鍵字然後在1999年之後進行了兩次技術修正,新出臺了C99標準新增加了5個關鍵字 分別是:restrict, inline, _Complex, _Imaginary, _Bool
  • Python 佔位符格式化詳解
    佔位符是絕大部分程式語言都存在的語法, 而且大部分都是相通的, 它是一種非常常用的字符串格式化的方式。1.常用佔位符的含義s : 獲取傳入對象的__str__方法的返回值,並將其格式化到指定位置r : 獲取傳入對象的__repr__方法的返回值,並將其格式化到指定位置c : 整數:將數字轉換成其unicode對應的值,10進位範圍為 0 <= i <= 1114111(py27則只支持0-255);字符:將字符添加到指定位置o : 將整數轉換成