stacic_cast
作用:對可轉換的類型進行相應的類型轉換
示例:
#include<iostream>
using namespace std;
int main() {
int a = 1;
int * b = (int *)a; //錯誤使用
//int *c = static_cast<int *>(a);//此處編譯報錯
int i = 5, j = 2;
double k = i / j;
cout << k << endl; //輸出爲2
double kk = static_cast<double>(i) / j;//進行強制轉換以便執行浮點數除法,正確使用
cout << kk << endl;
return 0;
}
說明:傳統C語言的強制轉換,可以編譯通過,但是將int類型轉換爲int*是沒有意義的,有的時候類似此類的轉換是有風險的,所以針對上述轉換濫用的問題,C++引入了相關的類型轉換,如下面代碼,當()中的內容與<>中的內容不能相互轉換時,編譯會報錯,這樣會方便查找錯誤,並且不會產生隱患。
const_cast
const_cast只能消除運算對象的底層const,因此const_cast中<>中的類型必須是,指針、引用或指向對象類型的成員的指針
#include<iostream>
#include<string>
using namespace std;
int main() {
const int a = 1;
//a = 2; //此處報錯,const類型不能修改
//int b = const_cast<int>(a); //此處報錯,const_cast中<>中的類型必須是,指針、引用或指向對象類型的成員的指針
string str{ "hello" };
const char * point = str.c_str();
cout << point << endl;
//char * point1 = point; //此處報錯。const char* 類型不能初始化 char *
char * point2 = const_cast<char *>(point);
cout << point2;
return 0;
}
reinterpret_cast
作用:爲運算對象的位模式提供較低層次的上的重新解釋,不到萬不得已不要使用,容易產生問題
例如:
#include<iostream>
#include<string>
using namespace std;
int main() {
int a = 1;
int *point = &a;
char *pc = reinterpret_cast<char *>(point); //提供較低層次,例如從int到char
}
dynamic_cast
dynamic_cast<type>(e)
type類型爲指針或引用(包括右值引用),e與type相對應。
/*這是從網上摘下的例子,主要講述了 dynamic_cast<> 的使用方法。*/
/*
作用:將一個基類對象指針(或引用)cast到繼承類指針,dynamic_cast會根據基類指針是否真正指向繼承類指針來做相應處理,
即會作一定的判斷。
對指針進行dynamic_cast,失敗返回null,成功返回正常cast後的對象指針;
對引用進行dynamic_cast,失敗拋出一個異常(bad_cast),成功返回正常cast後的對象引用。
注意:dynamic_cast在將父類cast到子類時,父類必須要有虛函數。例如在下面的代碼中將CBasic類中的test函數不定義成
virtual時,編譯器會報錯:error C2683: dynamic_cast : “CBasic”不是多態類型
對編譯器的要求:
dynamic_cast<> 會用到RTTI技術,因此需要啓動“運行時類型信息”這一選項,而在VC.net 2003中默認是關閉的。
所以需要人爲的啓動這一選項。否則編譯器會報下面的警告:
warning C4541: “dynamic_cast”用在了帶 /GR- 的多態類型“CBasic”上;
可能導致不可預知的行爲從而導致程序在運行時發生異常。
該設置在 Project->Setting中 C/C++ -> C++ Language中設置。
*/
#include <iostream>
using namespace std;
class CBasic
{
public:
virtual int test(){return 0;} // 一定要是 virtual
};
class CDerived : public CBasic
{
public:
virtual int test(){ return 1;}
};
int main()
{
CBasic cBasic;
CDerived cDerived;
CBasic * pB1 = new CBasic;
CBasic * pB2 = new CDerived;
//dynamic cast failed, so pD1 is null.
CDerived * pD1 = dynamic_cast<CDerived * > (pB1);
//dynamic cast succeeded, so pD2 points to CDerived object
CDerived * pD2 = dynamic_cast<CDerived * > (pB2);
//dynamci cast failed, so throw an exception.
// CDerived & rD1 = dynamic_cast<CDerived &> (*pB1);
//dynamic cast succeeded, so rD2 references to CDerived object.
CDerived & rD2 = dynamic_cast<CDerived &> (*pB2);
return 0;
}
轉自論壇的文章,地址http://bbs.byr.cn/#!article/SoftDesign/14689,使用中發現紅字部分以前沒注意過
爲什麼這種情況要用dynamic_cast,而不是用static_cast
class A {
private:
int a;
public:
virtual ~A() {}
};
class B :public A{
};
int main(){
A a;
A & ra = a;
//B &b = dynamic_cast<B &>(ra);//錯誤,會拋出異常
B &b = static_cast<B &>(ra); //不會報錯,在使用中會造成嚴重錯誤
}