一、 強制轉型
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 < type-id > ( exdivssion )
該運算子把exdivssion轉換為type-id型別,但沒有運行時型別檢查來保證轉換的安全性,它主要有如下幾種用法:
①用于類層次結構中基類和子類之間指標或參考的轉換,
進行上行轉換(把子類的指標或參考轉換成基類表示)是安全的;
進行下行轉換(把基類指標或參考轉換成子類表示)時,由于沒有動態型別檢查,所以是不安全的,
②用于基本資料型別之間的轉換,如把int轉換成char,把int轉換成enum,這種轉換的安全性也要開發人員來保證,
③把空指標轉換成目標型別的空指標,
④把任何型別的運算式轉換成void型別,
注意:static_cast不能轉換掉exdivssion的const、volitale、或者__unaligned屬性,
2 dynamic_cast
用法:dynamic_cast < type-id > ( 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);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/227210.html
標籤:C++
上一篇:求大佬指點!!!!!
