C++的四種強制類型轉換爲:static_cast、const_cast、reinterpret_cast和dynamic_cast
類型轉換的一般形式:cast-name(expression);
static_cast
任何具有明確定義的類型轉換,只要不包含底層const,都可以使用static_cast;
double slope = static_cast(j) / i;
注:
頂層const:表示指針本身是個常量。如:int *const p;
底層const:表示指針所指的對象是一個常量。如:int const *p;
const_cast
該運算符只能改變運算對象的底層const。
#include<iostream>
using namespace std;
int main()
{
const char *pc=" HDU";
char *p=const_cast<char *>(pc); //正確,
cout<<"hello"<<p<<endl;
return 0;
}
注:此處只能用const_cast,而不能用static_cast;
reinterpret_cast
通常爲運算對象的位模式提供較低層次上的重新解釋。
注:
1、在指針之間轉換,將一個類型的指針轉換爲另一個類型的指針,無關類型;
2、將指針值轉換爲一個整型數,但不能用於非指針類型的轉換。
dynamic_cast
只用於對象的指針和引用,不能用於內置的基本數據類型的強制轉換。
使用dynamic_cast進行轉換的,基類中一定要有虛函數,否則編譯不通過。
運行時類型識別,用於將基類的指針或引用安全地轉換成派生類的指針或引用。
對指針進行dynamic_cast,失敗返回null,成功返回正常cast後的對象指針;
對引用進行dynamic_cast,失敗拋出一個異常bad_cast,成功返回正常cast後的對象引用。
對於“向上轉換”(即派生類指針或引用類型轉換爲其基類類型),無論是指針還是引用向上轉換都是安全地。
對於“向下轉型”有兩種情況:
1、基類指針所指對象是派生類類型的,這種轉換是安全的;
2、基類指針所指對象爲基類類型,在這種情況下dynamic_cast在運行時做檢查,轉換失敗,返回結果爲0;
在引用上,dynamic_cast依舊是常用於“安全的向下轉型”。與指針一樣,引用的向下轉型也可以分爲兩種情況,與指針不同的是,並不存在空引用,所以引用的dynamic_cast檢測失敗時會拋出一個bad_cast異常。
#include <iostream>
#include <cstring>
using namespace std;
class A
{
public:
virtual void f()
{
cout << "hello" << endl;
}
};
class B: public A
{
public:
void f()
{
cout << "hello2" << endl;
}
};
int main()
{
A* a1=new B;//a1是A類型的指針指向一個B類型的對象
A* a2=new A;//a2是A類型的指針指向一個A類型的對象
B* b;
b=dynamic_cast<B*>(a1);
//結果爲not null,向下轉換成功,a1之前指向的就是B類型的對象,所以可以轉換成B類型的指針。
if(b==NULL)
cout<<"null"<<endl;
else
cout<<"not null"<<endl;
b=dynamic_cast<B*>(a2);//結果爲null,向下轉換失敗
if(b==NULL)
cout<<"null"<<endl;
else
cout<<"not null"<<endl;
return 0;
}
總結
基本類型轉換用static_cast。
去const屬性用const_cast。
不同類型的指針類型轉換用reinterpreter_cast。
多態類之間的類型轉換用daynamic_cast。
C++ 4種強制類型轉換
C++的四種強制類型轉換爲:static_cast、const_cast、reinterpret_cast和dynamic_cast
類型轉換的一般形式:cast-name(expression);
static_cast
任何具有明確定義的類型轉換,只要不包含底層const,都可以使用static_cast;
double slope = static_cast(j) / i;
注:
頂層const:表示指針本身是個常量。如:int *const p;
底層const:表示指針所指的對象是一個常量。如:int const *p;
const_cast
該運算符只能改變運算對象的底層const。
#include<iostream>
using namespace std;
int main()
{
const char *pc=" HDU";
char *p=const_cast<char *>(pc); //正確,
cout<<"hello"<<p<<endl;
return 0;
}
注:此處只能用const_cast,而不能用static_cast;
reinterpret_cast
通常爲運算對象的位模式提供較低層次上的重新解釋。
注:
1、在指針之間轉換,將一個類型的指針轉換爲另一個類型的指針,無關類型;
2、將指針值轉換爲一個整型數,但不能用於非指針類型的轉換。
dynamic_cast
只用於對象的指針和引用,不能用於內置的基本數據類型的強制轉換。
使用dynamic_cast進行轉換的,基類中一定要有虛函數,否則編譯不通過。
運行時類型識別,用於將基類的指針或引用安全地轉換成派生類的指針或引用。
對指針進行dynamic_cast,失敗返回null,成功返回正常cast後的對象指針;
對引用進行dynamic_cast,失敗拋出一個異常bad_cast,成功返回正常cast後的對象引用。
對於“向上轉換”(即派生類指針或引用類型轉換爲其基類類型),無論是指針還是引用向上轉換都是安全地。
對於“向下轉型”有兩種情況:
1、基類指針所指對象是派生類類型的,這種轉換是安全的;
2、基類指針所指對象爲基類類型,在這種情況下dynamic_cast在運行時做檢查,轉換失敗,返回結果爲0;
在引用上,dynamic_cast依舊是常用於“安全的向下轉型”。與指針一樣,引用的向下轉型也可以分爲兩種情況,與指針不同的是,並不存在空引用,所以引用的dynamic_cast檢測失敗時會拋出一個bad_cast異常。
#include <iostream>
#include <cstring>
using namespace std;
class A
{
public:
virtual void f()
{
cout << "hello" << endl;
}
};
class B: public A
{
public:
void f()
{
cout << "hello2" << endl;
}
};
int main()
{
A* a1=new B;//a1是A類型的指針指向一個B類型的對象
A* a2=new A;//a2是A類型的指針指向一個A類型的對象
B* b;
b=dynamic_cast<B*>(a1);
//結果爲not null,向下轉換成功,a1之前指向的就是B類型的對象,所以可以轉換成B類型的指針。
if(b==NULL)
cout<<"null"<<endl;
else
cout<<"not null"<<endl;
b=dynamic_cast<B*>(a2);//結果爲null,向下轉換失敗
if(b==NULL)
cout<<"null"<<endl;
else
cout<<"not null"<<endl;
return 0;
}
總結
基本類型轉換用static_cast。
去const屬性用const_cast。
不同類型的指針類型轉換用reinterpreter_cast。
多態類之間的類型轉換用daynamic_cast。