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

2020-12-12 騰訊網

一、 強制轉型

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);

}

相關焦點

  • 4 種 C++ 強制類型轉換,你都清楚嗎?
    強制類型轉換的形式:其中,type是轉換的目標類型,exper是要轉換的值,cast-name 有以下四種:static_castdynamic_castconst_castreinterpret_cast接下來,我們逐個進行分析。
  • 釐清C++類型轉換
    說起來也很簡單,舉個慄子:char x = 'c';int y = (int) x;這是最簡單的一個舊式類型轉換,一個char類型被裝換為一個int類型。2、新式的類型轉換C++語言提供了四種新式類型轉換的操作:static_cast,dynamic_cast,reinterpret_cast,const_cast,這些操作都依託了C++的模板來使用,標準的用法是xxx_cast<轉換類型>(轉換參數)這種新式轉換優於舊式的轉換就在於:
  • c++之內存分配、命名空間、強制類型轉換學習總結
    強制類型轉換類型匯總static_castconst_castdynamic_castreinterpret_cast用法:xxx_cast(Expression)下面是每種強制類型的具體講解:1、static_cast強制類型轉換:代碼解析:#include <stdio.h>void static_cast_demo
  • 誰說C++ 的強制類型轉換很難懂?
    static_cast在C++中,staticcast相當於C語言中的強制類型轉換語法。staticcast用於在編譯期對某種類型的變量進行強制類型轉換。參考以下代碼:intmain(){static_cast<int *>(malloc(0));static_cast<int>(0.)
  • 詳細介紹下C/C++那些時間函數
    首先介紹下C++標準中的chrono庫chrono是一個關於時間的庫,起源於boost,現在是C++的標準,話說現在的C++標準好多都是源於boost,要進標準的特性似乎都會先在boost試驗一番。標準庫還提供了duration_cast用於轉換各種duration。
  • C++的轉換手段並與explicit關鍵詞配合使用
    reinterpret_cast,僅僅重新解釋類型,但沒有進行二進位的轉換。static_cast:任何具有明確定義的類型轉化,只要不包含底層const,都可以使用static_cast,舉一個例子。void*p = &n;double*d = static_cast<double*>(&p) //將void*轉化為初始的指針類型static_cast強制轉換隻會在編譯時檢查,但沒有運行時類型檢查來保證轉換的安全性。
  • 詳解C++ 的隱式類型轉換與函數重載!
    存在精確匹配的類型轉換參考以下代碼:structA {operatorint(){ return0; } operatordouble(){ return0.; } };intmain(){static_cast<double
  • C語言小白學習――數據類型的轉換及轉換規則
    1.不同類型數據間的混合運算與類型轉換: ①若參與運算量的類型不同,則先轉換成同一類型,然後進行運算②轉換按數據長度增加的方向進行,以保證精度不降低。如int型和long型運算時,先把int量轉成long型後再進行運算a、若兩種類型的字節數不同,轉換成字節數高的類型b、若兩種類型的字節數相同,且一種有符號,一種無符號,則轉換成無符號類型③所有的浮點運算都是以雙精度進行的,即使僅含float單精度量運算的表達式,也要先轉換成double型,再作運算④char型和short型參與運算時,必須先轉換成
  • 面試官:聊聊 C++ static 和 const
    /questions/15235526/the-static-keyword-and-its-various-uses-in-c?c;將函數返回值或者參數修飾為 const,可以避免客戶或函數內部修改該變量。
  • C語言與C++面試知識總結
    bool() 的從 A 到 bool 的隱式轉換bool a8 = static_cast<bool>(a1); // OK :static_cast 進行直接初始化B b1(1);// OK:直接初始化B b2 = 1;// 錯誤:被 explicit 修飾構造函數的對象不可以複製初始化B b3{ 1 };// OK:直接列表初始化B
  • C語言中的變量存儲類型static老手都這樣用
    變量存儲類型關係到其存儲位置,除了register型存儲在CPU寄存器中,C語言提供的其它三種存儲類型(auto型、static型、extern型)的變量均存儲在內存中。存儲位置不同,決定了變量的生存期和作用域。具體變量介紹請見作者的另一篇文章,名為《說一說C語言中的變量存儲類型——「extern」》。
  • C/C++中常用的編程關鍵字
    16. dynamic_castdynamic_cast(動態轉換),允許在運行時刻進行類型轉換,從而使程序能夠在一個類層次結構安全地轉換類型。dynamic_cast 提供了兩種轉換方式,把基類指針轉換成派生類指針,或者把指向基類的左值轉換成派生類的引用。
  • 話說const修飾符與static修飾符
    出自:彭磊 編程小小屋連結:http://mp.weixin.qq.com/s/t6kA6UqZnQTOA687CvKCUA1 C中的const和static:這也是面試和筆試中經常會考到的問題,特別是static我面試了四家就考了兩家,但是一般會放在前兩題,屬於特別基礎的題目了
  • 第112講 字符轉換
    在說boost之前,我們先來看一個小工具,這是一個關於字符轉換的工具,他可以取代c庫中的atoi這些小函數,但同時他更加安全。 為了實現更加安全和更具有魯棒性的轉換,首先我們寫一個自己的異常類,這個異常類主要是針對字符轉換,所以我們從std::bad_cast來繼承他。
  • 你所不知道的C語言高級用法
    如果 int可以表示原始類型的所有值,那麼這個操作數會轉換成 int,否則他會轉換成 unsigned int。下面這個函數在 32 位平臺返回 65536,但是在 16 位系統返回 0。4.違反類型規則把int×指針cast成float×,然後對它解引用,在C裡面會引發undefined behavior,C規定這種類型的轉換需要使用memset,C++裡面有個reinterpret_cast函數用於無關類型之間的轉換,reinterpret_cast (expression)防止內存洩漏
  • Fluent UDF【4】:C語言
    例如:注釋也可以跨行實現,如:注意:在編寫UDF的過程中,不能把DEFINE宏(如DEFINE_PROFILE)放置在注釋中,否則會引起編譯錯誤2 基本數據類型Fluent UDF解釋器支持的標準C數據類型包括:int。