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

2020-12-23 騰訊網

一、 強制轉型

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++的轉換手段並與explicit關鍵詞配合使用
    reinterpret_cast,僅僅重新解釋類型,但沒有進行二進位的轉換。static_cast:任何具有明確定義的類型轉化,只要不包含底層const,都可以使用static_cast,舉一個例子。void*p = &n;double*d = static_cast<double*>(&p) //將void*轉化為初始的指針類型static_cast強制轉換隻會在編譯時檢查,但沒有運行時類型檢查來保證轉換的安全性。
  • C/C++中常用的編程關鍵字
    16. dynamic_castdynamic_cast(動態轉換),允許在運行時刻進行類型轉換,從而使程序能夠在一個類層次結構安全地轉換類型。dynamic_cast 提供了兩種轉換方式,把基類指針轉換成派生類指針,或者把指向基類的左值轉換成派生類的引用。
  • C++中的static
    static。 3、靜態函數    在函數的返回類型前加上static關鍵字,函數即被定義為靜態函數。靜態函數與普通函數不同,它只能在聲明它的文件當中可見,不能被其它文件使用。 #include <iostream.h>   class Myclass   {    public:    Myclass(int a,int b,int c);   void GetSum();  private: int a,b,c;   static int Sum;//聲明靜態數據成員   };   int Myclass::Sum=
  • 【揭秘】C語言類型轉換時發生了什麼?
    ,所以就出現了類型轉換。 對於某些類型的轉換,編譯器可以隱式地自動進行,這種轉換稱為自動類型轉換; 而有些類型轉換需要程式設計師顯式指明,那麼通常把這種轉換稱為強制類型轉換。 自動類型轉換 自動轉換是在源類型和目標類型兼容以及目標類型廣於源類型時發生一個類型到另一類的轉換。
  • Java基礎入門之多態和對象類型轉換
    Java基礎入門之多態和對象類型轉換 假設實現一個動物發出的叫聲方法,我們知道不同的動物,它們的叫聲是不一樣的。當在方法中傳入一個參數類型,例如貓的叫聲、狗的叫聲。在同一個方法,當參數不同它們的執行結果各不相同,這就是多態。
  • java中static, final, 內部類的具體運用
    static概念:static它是靜態修飾符,一般用來修飾類中的成員。當在定義類的時候,類中都會有相應的屬性和方法。而屬性和方法都是通過創建本類對象調用的。static特點:static是靜態修飾符,一般修飾成員。被static修飾的成員屬於類,不屬於單個這個類的某個對象。
  • C/C++編程筆記:C++的修飾符類型
    C++ 允許在 char、int 和 double 數據類型前放置修飾符。修飾符用於改變基本類型的含義,所以它更能滿足各種情境的需求。
  • 如何用Bull轉換任意類型的Java Bean
    } }但是,我們可以將庫配置為為欄位類型分配默認值(如:0為int類型,null為String等等)ToBean toBean = new BeanUtils().getTransformer
  • C語言數據類型思維導圖怎麼製作
    使用思維導圖來梳理各個數據類型是一個很有效的記憶方法,接下來就為大家展示一下我用iMindMap製作的關於C語言基本數據類型的思維導圖。一、整型1.整型類型圖片1:整型的類型如圖所示,整型數據的類型主要有六種,分類標準為有無符號(signed或unsigned)和長短(long或short),整型的基本表示是int。
  • C語言編程核心要點
    類型C是強類型語言,有short、long、int、char、float、double等build-in數據類型,類型是貫穿c語言整個課程的核心概念。struct、union、enum屬於c的構造類型,用於自定義類型,擴充類型系統。變量變量用來保存數據,數據是操作的對象,變量的變字意味著它可以在運行時被修改。
  • 「Java」基礎19:修飾符有哪些?
    這就得學到一個新的修飾符了。一、final修飾符final,翻譯成中文就是「不可更改的 」。顧名思義,它是一個修飾符,用於修改不可更改的內容。被final修飾的類:不能被繼承。基本數據類型不能更改的是值。④用final修飾引用數據類型局部變量。只能創建對象一次,不能再次創建對象,編譯會報錯。引用數據類型不能更改的是對象的地址。
  • 一文讀懂js中的隱式類型轉換
    前言今天來詳細了解一下javascript中的隱式類型轉換,通過在各種情況下發生的隱式類型的例子,來詳細的了解隱式類型轉換的過程。如何轉換-前置知識1.對象類型轉換當對象類型進行類型轉換時,會調用js內部一個方法toPrimitive, 此方法接收兩個參數,一個參數為需要轉換的對象,另一個方法接收一個期望類型,string或number。
  • static和final,今天的文章要說的就是訪問控制中的這兩個關鍵字
    昨天的一篇文章介紹了訪問控制中的訪問修飾符以及它們的訪問權限。下面這篇文章我們介紹訪問控制中的第二部分static和final關鍵字。static關鍵字static修飾成員變量用static修飾的成員變量不屬於對象的數據結構,static變量是屬於類的變量,通常可以通過類名來引用static成員。
  • java基本數據類型的自動裝箱、自動拆箱
    這裡就涉及到了java基本數據類型的自動裝箱和自動拆箱了。像上面代碼中「Integer b = 5;」這句就會用到自動裝箱,會把基本數據類型的int值5自動封裝成一個Integer類型的對象。這裡會用到Integer類的「public static Integer valueOf(int i)」方法。我們來看看Integer的這個方法。這裡的low是-128,high是127。也就是說如果是要對這兩個值之間的int值做裝箱時,是從緩存中取對應的Integer對象。
  • JAVA基礎教程:JAVA的基本數據類型及介紹
    使用強制數據類型轉換,防止溢出:public class DataDemo03{public static main(String args[]){int max = Integer.MAX_VALUE; // 得到整型的最大值