static_cast&dynamic_cast

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類型,但反之不行。

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