標準C++中爲了加強類型轉換的可視性,引入了四種命名的強制類型轉換操作符。
static_cast
reinterpret_cast
const_cast
dynamic_cast
爲了更好的理解C++中的類型轉換,我們先講講我們在C語言中的轉換。
#include<iostream>
void test()
{
int i = 2;
double d = i;
printf("隱式類型轉換:i = %d, d = %f\n ", i, d);
int *p = &i;
int address = (int)p;
printf("強制類型轉換:p = %x,address = %d", p, address);
}
int main()
{
test();
return 0;
}
打印結果:
強制轉換的可視性比較差,所有的轉換形式都是以同一種相同形式書寫,難以跟蹤錯誤的轉換。
C++中爲了加強類型轉換的可視性,引入了四種類型轉換操作符
static_cast:
static_cast用於非多態類型的轉換(靜態轉換),編譯器隱式執行的任何類型轉換都可用static_cast,但它不能用於兩個不相干的類型進行轉換
int main()
{
double d = 3.14;
int a = static_cast<int>(d);
std::cout << a << std::endl;
return 0;
}
//輸出爲3
reinterpret_cast:
用於將一種類型轉換爲另一種不同的類型。
typedef void(*FUNC)();
int dosomething(int i)
{
cout << "dosomething" << endl;
return 0;
}
void test()
{
FUNC f = reinterpret_cast<FUNC>(dosomething);
f();
}
int main()
{
test();
return 0;
}
//輸出:desomething
const_cast:
const_cast最常用的用途就是刪除變量的const屬性,方便賦值。
void Test ()
{
const int a = 1;
int* p = const_cast< int*>(&a );
*p = 3;
cout<<a <<endl;
}
//輸出:3
dynamic_cast:
dynamic_cast用於將一個父類對象的指針轉換爲子類對象的指針或者引用(動態轉換)
注意點:
1,dynamic_cast只能用於含有虛函數的類
2,dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回0
class A
{
public :
virtual void f()
{}
};
class B : public A
{};
void test (A* pa)
{
B* pb1 = static_cast<B*>(pa);
B* pb2 = dynamic_cast<B*>(pa);
cout<<"pb1:" <<pb1<< endl;
cout<<"pb2:" <<pb2<< endl;
}
int main ()
{
A a;
B b;
test(&a);
test(&b);
return 0;
}
打印爲:
Explicit關鍵字
C++中的關鍵字explicit主要是用來修飾類的構造函數,被修飾的構造函數的類,不能發生相應的隱式類型轉換,只能以顯示的方式進行類型轉換。隱式轉換即是可以由單個實參來調用的構造函數定義了一個從形參類型到該類類型的隱式轉換。
一般只將有單個參數的構造函數聲明爲explicit,而拷貝構造函數不要聲明爲explicit。