stactic_cast用來執行任意明確定義的類型轉換,以及反變換。但其只是暴力轉換,並不負責保證轉換的安全性。
1、基本數據類型之間的轉換,int->char,int->enum,char->int,int->float,float->int,但精度的丟失不在static_cast的考慮範圍,需要開發者自己考慮。
2、將任何非常量對象的地址存入void* & 找回存在於void*指針中的值。
char *c = new char[100];
c = "12222";
cout<<c<<endl;
這裏c本身是一個指向字符數組的指針,但cout語句中,對於const char*或者 char*類型的指針,只會輸出他們指向的值,而不會輸出其本身存儲的地址。如果想輸出地址,只能顯示轉換一下,void* ptr = static_cast<void*>(c),此時即可輸出c保存的地址;
同理也可以用static_cast進行上述過程的逆過程,如果有一個指針因爲要獲取地址的原因被顯示轉換成了void*,此時想將其轉換回來,則可以這樣使用:char *ptr2 = static_cast<char*>(ptr);此時cout<<ptr2;即可輸出值而非地址。
char* c = new char[100];
c = "12222";
cout << "c: " << c << " ";
void* ptr1 = static_cast<void*>(c);
cout << "ptr1: " << ptr1<<" ";
char* ptr2 = static_cast<char*>(ptr1);
cout << "ptr3: " << ptr2;
cout << endl;
輸出結果:
3、類層次結構中父類與子類之間指針或者引用的轉換。&dynamic_cast
類中父類子類之間的指針、引用轉換有兩類情況,一類是從父類轉換爲子類,另一類是從子類轉換爲父類。前者叫下行轉換,後者叫上行轉換。上行轉換較爲安全,但下行轉換並不安全。
A *ptr = new A;
C *cptr = static_cast<C*>(ptr);
C *dptr = dynamic_cast<C*>(ptr);//必須有多態產生,纔可用dynamic_cast
cout << "cptr:" << cptr << " dptr: " << dptr;
其中類定義如下:
class A{
public:
A() = default;
virtual void func(){}
int m; };
class B{ int m; };
class D{
virtual void func(){};
};
class C :public A, B{
public:
int temp;
};
由於類的繼承關係,指向父類指針既可以指向子類對象,也可以指向子類對象。但子類指針不可指向父類對象,這就是問題所在。
上述情況即一個指向父類對象的父類指針,被強制轉換爲一個指向父類對象的子類指針,因爲子類中可能有父類中沒有的屬性與函數,如果用轉換過後的指針去訪問子類專屬的成員,那就會造成訪問越界,內存崩潰。如果使用static_cast強行轉換,程序不會報錯,也不會做運行時類型檢查,這就是一個巨大的隱患。
dynamic_cast所做的就是在運行時進行類型檢查,此時,檢測到這樣的轉換不合適,就會將轉換後的指針置NULL,保證程序不會崩潰。
因爲引用沒有NULL引用,所以dynamic_cast引用遇到此類情況,就會拋出std::bad_cast異常。
tip:static_cast & dynamic_cast可以做從非const類型到const類型,但反之不行。