程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++四種類型轉換

C++四種類型轉換

編輯:C++入門知識

C++四種類型轉換


在C/C++語言中用 (type) value(還可以采用type(value))來進行顯式類型轉換,常常又被稱為強制轉換。這種轉換的正確性完全掌握在程序員手中,傳統上強制轉換往往被過度使用,成為C++程序犯錯的一個主要根源。

為了減少強制轉換的副作用,並且在查錯時使程序員能夠快速定位(總是最值得懷疑的)強制轉換,在標准C++中新增加了4個關鍵字*_cast,用來提倡一種全新的C++顯式轉換語法:

	*_cast  (expression) 

static_cast(靜態轉換)

用於明確定義良性和適度良性的轉換,包括原來不需要采用強制轉換的自動類型轉換(包括無損的提升轉換和可能丟失信息的窄化轉換[narrowing conversion],對後者編譯器一般會提出警告)。 標准C++提倡對任何數據的類型轉換(不論是自動的還是強制的),都采用新的*_cast顯式類型轉換方法。例如:

    int i = 0x7fff;
    long l;
    float f;
    char c;
// (1)典型的非強制轉換(自動轉換)
// 傳統方式:
    l = i;
    f = i;
// 提倡的新方式:
    l = static_cast(i);
    f = static_cast(i);

// (2)窄化轉換
// 傳統方式:
// 會顯示警告信息:
    i = l; // 可能丟失數字
    i = f; // 可能丟失信息
    c = i; // 可能丟失數字
// 不顯示警告信息(但仍然難定位):
    i = (int)l;
    i = (int)f;
    c = (char)i;
// 提倡的新方式(不會顯示警告信息,且易定位):
    i = static_cast(l);
    i = static_cast(f);
    c = static_cast(i);

const_cast(常量轉換)

可將(同數據類型的)常型(const)轉換為非常型、將易變(volatile)型轉換為非易變型。如果用於其他類型的轉換,一般會產生一個編譯錯誤。例如:

    const int i = 0;
    int *pi;
    pi = &i; // 錯誤
    pi = (int *)&i; // 被反對
    pi = const_cast(&i); // 完美
    long *pl = const_cast(&i); // 錯誤
    volatile int k = 0;
    int *pk = const_cast(&k); // 正確 

dynamic_cast(動態轉換)

一種安全的向下類型轉換(downcast)操作,用於在一個類繼承層次上向下移動。

因為每個派生類的基類都只有一個,而且派生類本身又包含了幾乎所有的基類信息(private型的除外),所以向上的類型轉換(upcast)總是唯一的和比較安全的。

而一個基類往往有多個派生類,而且派生類中一般會在基類的基礎上添加了一些特有的數據和操作,所以向下的類型轉換總是多態的和不太安全的。

dynamic_cast提供了一種安全的向下類型轉換操作,只有當類型轉換是正確的並且轉換取的成功,返回值才是所需要的指針;否則它將返回0(空指針NULL),表示不是正確的類型。

例如:

    class Pet
    {
        //……
    };
    class Dog : public Pet
    {
        //……
    };
    class Cat : public Pet
    {
        //……
    };

    Pet *pPet = new Cat; // 向上的類型轉換
    Dog *pDog = dynamic_cast(pPet); // 類型錯誤,返回0(NULL)
    Cat *pCat = dynamic_cast(pPet); // 類型正確,返回指針
    Cat *pCat = static_cast(pPet); // 正確,減少運行時的開銷 

注意:dynamic_cast雖然安全,但是運行時需要一定開銷,因此不提倡大量使用這種轉換。如果你已經能夠確認轉換的正確性,則可以采用前面介紹過的(無運行時開銷的)static_cast轉換。只有當你實在無法確定轉換是否正確時,才需要采用dynamic_cast轉換。

reinterpret_cast(重解釋轉換)

一種最有可能出問題的最不安全的類型轉換。只是在下面的情形,才需要使用這種類型轉換:當需要使用時,所得到的東西已經不同了,為了使它能夠用於原來的目的,必須再次把它轉換回來。

例如:

    const int sz = 100; // 定義數組大小,標准C++提倡用常型變量(而不是常數或符號常量宏)
    struct X
    {
        int a[sz];
    }; // 只包含一個整數數組的結構

    X x; // 定義結構變量,此時結構中的數組元素的值無意義(需要初始化)
    int *px = reinterpret_cast (&x); // 為了初始化,先把結構轉化為int數組
    for (int *i = px; i < px + sz; i++) *i = 0; // 將每個數組元素的值初始化為0
    print(reinterpret_cast (px)); // 重新轉換成結構指針,以便使用,也可以直接使用原來的標識符x,此語句相當於print(&x);

使用reinterpret_cast通常是一種不明智且不方便的編程方式。但是在必須使用時,它也是非常有用的。

總結:

在這四種強制轉換中,static_cast最常用(目前還沒有流行起來,但是被標准C++著力提倡)、dynamic_cast最重要、const_cast也有用、而reinterpret_cast則很少被使用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved