C++ 四類類型轉換,static_cast, const_cast, reinterrupt_cast, dynamic_cast給v

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); //不會報錯,在使用中會造成嚴重錯誤
}

 

 

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