C++的類型轉換

C++的類型轉換

——顯示轉換VS隱式轉換、轉換函數

       合理的轉換可以使得程序更加簡潔,不合理的轉換往往導致程序錯誤和崩潰。C++類型的轉換可以分爲顯式轉換和隱式轉換兩種,顯示轉換是指通過類型轉換函數對類型進行轉換,隱式類型轉換是指由編譯器自動生成的轉換。隱式轉換的前提是存在合理的轉換對象。

l  隱式類型轉換髮生的場合——build-in類型

1.         兩種不同類型值進行比較或進行運算

       這種隱式轉換是最常見的轉換,又叫做整型提升(integral promotion。所有的比較操作符(==、>=、<=、!= )和算數運算符(+、-、*、/)都會出現這種情形。轉換規則是可以將char、signed char、unsigned char、short、and unsigned short提升到int。

E.g. bool      flag;         char           cval;

     short     sval;         unsigned short usval;

     int       ival;         unsigned int   uival;

     long      lval;         unsigned long  ulval;

     float     fval;         double         dval;

     3.14159L + 'a'; // promote 'a' to int, then convert to long double

     dval + ival;    // ival converted to double

     dval + fval;    // fval converted to double

     ival = dval;    // dval converted (by truncation) to int

     flag = dval;    // if dval is 0, then flag is false, otherwise true

     cval + fval;    // cval promoted to int, that int converted to float

     sval + cval;    // sval and cval promoted to int

     cval + lval;    // cval converted to long

     ival + ulval;   // ival converted to unsigned long

     usval + ival;   // promotion depends on size of unsigned short and int

     uival + lval;   // conversion depends on size of unsigned int and long

        ival >= dval  // ival converted to double

 

2.         表達式轉換成bool類型

出現的情形有:

Ø  條件判斷語句中:if、while、for、do while和操作符(?:)的第一個判斷中。

Ø  邏輯操作符:邏輯非(!)、邏輯與(&&)和邏輯或(||)

只有當該類型的值爲0時,才能轉換成false,其他值都爲true。NULL指針類型可以轉換爲false,其他指針轉換後爲true。

E.g. int ival;

if (ival)   // ival converted to bool, true if cp is not zero

while (cin) // cin converted to bool

while (cin >> s) //如果讀取失敗,則返回false,否則返回true

 

3.         表達式進行賦值

E.g. int ival = 3.14; // 3.14 converted to int

     int *ip;

     ip = 0; // the int 0 converted to a null pointer of type int *

 

4.         指針轉換

指針轉換有兩種類型:任何指針類型都可以轉換成void *,常值0可以轉換成指針類型。數組可以自動轉換成指向數組中第一個元素的指針。

int ia[10];    // array of 10 ints

int* ip = ia;  // convert ia to pointer to first element

 

5.         枚舉類型轉換

枚舉類型可以自動地轉換成int類型。

// point2d is 2, point2w is 3, point3d is 3, point3w is 4

enum Points { point2d = 2, point2w, point3d = 3, point3w };

const size_t array_size = 1024;

// ok: pt2w promoted to int

int chunk_size = array_size * pt2w;

int array_3d = array_size * point3d;

 

6.         Non-const對象轉換成const對象

這種轉換髮生在用一個non-const對象初始化一個const對象。

int i;

const int ci = 0;

//j是i的別名,雖然j是不可變的,但是i可變

const int &j = i;   // ok: convert non-const to reference to const int

const int *p = &ci; // ok: convert address of non-const to address of a const

 

7.         函數參數傳遞以及函數返回值類型轉換

 

l  隱式類型轉換髮生的場合——類定義

l  顯式轉換使用的操作符

1.         static_cast<type>(expression);

build-in類型之間隱式轉換也可以用static_cast來進行顯式轉換。不過一般都在將較大類型轉換成較小類型時使用,告訴編譯器不必在乎精準度的損失。static_cast還有一種用法是將void*轉換成合適類型的指針。static_cast不能進行無關類型(如非基類和子類)指針之間的轉換。

E.g. double d = 97.0;

char ch = static_cast<char>(d); // cast specified to indicate that the conversion is intentional

void* p = &d; // ok: address of any data object can be stored in a void*

// ok: converts void* back to the original pointer type

double *dp = static_cast<double*>(p);

int n;

double *d = static_cast<double *>(&n) //無關類型指針轉換,編譯錯誤

 

2.         const_cast<type>(expression);

用來去掉類型的const或volatile屬性。

 

3.         dynamic_cast<type>(expression);

dynamic_cast將指向基類的指針轉向指向派生類指針。通常這是因爲使用基類的時候需要調用派生類的函數。一般會在基類中使用虛函數,派生類繼承的時候就可以通過繼承,用不同的方法實現該方法。將父類指針指向基類,可能發生錯誤,bad_cast

主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。

必須要有虛函數。子類繼承父類的虛函數,不同子類實現方式不同。子類也可以複寫父類的虛函數,可以根據類的不同使用不同的函數。

相同基類不同子類之間的交叉轉換。但結果是NULL

if (Derived *derivedPtr = dynamic_cast<Derived*>(basePtr)) {

         // use the Derived object to which derivedPtr points

} else { // BasePtr points at a Base object

         // use the Base object to which basePtr points }

void f(const Base &b){

try {

         const Derived &d = dynamic_cast<const Derived&>(b);

        // use the Derived object to which b referred

    } catch (bad_cast) {

            // handle the fact that the cast failed

    }    }

父類指針不能使用dynamic_cast轉換成子類指針,編譯報錯!

 

 

4.         reinterprete_cast

reinterprete_cast常用來用不同的bit pattern來轉換操作數,這種轉換與機器密切相關。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章