1.類型轉換是一種機制,可以讓程序員暫時或永久改變編譯器對對象的解釋
2.c++提供了4種類型轉換運算符static_cast dynamic_cast reinterpret_cast const_cast
3.static_cast用於相關類型之間的轉換。再轉換指針的時候,static_cast會進行基本的檢測
cbase是cderived的一個父類
cbase * pbase = new cderived();//這裏創建了一個cderived的對象,指針類型定義的時cbase
cderived * pderived = static_cast<cderived*> (pbase);//這一段代碼是正確的,把cbase的指針換成了cderived的指針,並賦值給pderived。
這本身也是正確的,因爲pbase指向的位置被來就是一個cderived的對象
下面這個代碼就是錯誤的
cunrelated * punrelated = static_cast6<cunrelated>(pbase);
這是因爲pbase和cunrelated沒有任何關係,不能把不同的類型的類的對象進行強制轉換
但是static_cast 只會進行指針類型的檢測,並不會對運行階段進行檢測,下面的代碼也是錯誤的,
cbase * pbase = new cabse();
cderived * pderived = static_cast<cderived*>(pbase);
這是因爲pbase是一個cbase的實例,如果轉換成cderived的類型,那麼在調用一些在cbase中沒有但是cderived中擴充的方法時,就會出錯。
語法上沒有問題,但是邏輯上,在程序運行時可能會導致錯誤
double a=1.234;
int b=a;
上面這個是隱式的轉換,b的值是1.通過static_cast可以顯示的進行轉換。
int b=static_cast<int>(a);
4.dynamic_cast
動態類型轉換,在運行階段進行轉換
cbase *pbase = new cderived();
cderived *pderived = dynamic_cast<cderived*>(pbase);
if(pderived)
{
pderived->callfunction();
}
上面代碼就是一個dynamic_cast的例子。就是創建一個父類的指針,但是指向的內容是一個子類的對象。然後把這個父類的指針進行轉換成一個子類的指針,判斷是否成功,如果成功,則調用子類的函數
這樣做的意義在於,當你在程序運行過程中,如果碰到一個父類指針,但是不能確定到底指向的是那個子類,可以用這個方法進行判斷,並依據情況做出不同的響應
class canimal
{
public:
virtual void speak()=0;
};
class cdog: public canimal
{
public:
void wagtail(){cout <<"dog wag"<<endl;}
void speak(){cout<<"dog bow"<<endl;}
};
class ccat : public canimal
{
public:
void catchmice(){cout<<"cat catch"<<endl;}
void speak(){cout<<"cat meow"<<endl;}
};
void determinetype(canimal *panimal)
{
cdog * pdog = dynamic_cast<cdog*>(panimal);
if(pdog)
{
cout << "dog"<<endl;
pdog->wagtail();
}
ccat * pcat = dynamic_cast<ccat *>(panimal);
if(pcat)
{
cout <<"cat"<<endl;
pcat->catchmice();
}
5.reinterpret_cast
由名字可以知道,這個是對類型進行重新定義然後轉換。也就是可以把兩個沒有任何關係的類型進行轉換。一般我們不會用到這些,因爲這樣沒有意義,也會導致很多問題。但是在驅動編程等低級程序裏面,卻會用到。因爲比較底層可能有的類型沒有或是不支持。但是我們可以轉換成二進制或是一些基本的格式,不改變數據,自己進行解析
cclass *pobject = new cclass();
unsigned char *pbyte = reinterpret_cast<unsigned char*>(pobject);
6.const_cast
這個就是解除const的作用。比如,我有個const變量要傳遞給一個函數,但是函數的參數確不是const的,這個時候就需要把這個const變量解除const然後傳遞給函數
void Printer (int* val)
{
cout << val<< endl;
}
int main(void)
{
const int consatant = 20;
Printer(const_cast<int *>(&consatant));
return 0;
}