1.什么是類型轉換
在傳統C語言中,由強制類型轉換和隱式類型轉換,隱式類型轉換,編譯器在在編譯階段自動處理,能轉換則轉換,強制類型轉換由用戶自己轉換。
缺陷:
- 轉換的可視性比較差,所有的轉換形式都是以一種相同形式書寫,難以跟蹤錯誤的轉換
- 隱式類型轉化有些情況下可能會出問題:比如數據精度丟失
- 顯式類型轉換將所有情況混合在一起,代碼不夠清晰
?
比如:
??? int a = 100;
?? ?long long b = a;//隱式類型轉換
?? ?char c = b;//隱式類型轉換
?? ?size_t d = a;//隱式類型轉換
?? ?cout << a <<" " <<" " << b <<" " << c <<" " << d << endl;
?? ?//強制類型轉換
?? ?double e = (double)a;
?? ?float f = (double)e;
?? ?cout << e << " " << f << endl;
在C++中,也可以使用C語言的轉換方式,但在C++中,有自己的轉換方式,
標準C++為了加強類型轉換的可視性,引入了四種命名的強制類型轉換操作符:
static_cast、reinterpret_cast、const_cast、dynamic_cast
2.不同操作符使用場景
2.1 static_cast使用
在static_cast中,它的使用方法相對于C語言中的隱式類型轉換,只能轉換兩種類型比較接近的,不能用于不相干類型的轉換。
比如:
??? int a = 100;
?? ?char b= static_cast<char>(a);
?? ?//char* c = static_cast<char*>(a);//無法轉換
?? ?cout << b << endl;
2.2 reinterpret_cast使用
reinterpret_cast操作符通常為操作數的位模式提供較低層次的重新解釋,強制轉換兩種不相關的類型,即一種類型轉換為另一種不相干的類型,
比如:
??? int a = 100;
?? ?char b= static_cast<char>(a);
?? ?char* c = static_cast<char>(b);//無法轉換?? ?char* c = reinterpret_cast<char*>(b);
?? ?printf("%c\n", *(&c));
2.3 const_cast使用
const_cast最常用的用途就是刪除變量的const屬性,方便賦值,但是需要使用volatile修飾加了const的變量。
比如:
???? volatile const int a = 10;
?? ? int* p? =const_cast<int*>(&a);
?? ? p = (int*)&a;
?? ?*p = 20;
?? ?cout << *p <<" " << a << endl;
2.4 dynamic_cast使用方法
dynamic_cast用于將一個父類對象的指針/引用轉換為子類對象的指針或引用(動態轉換)
向上轉型:子類對象指針/引用->父類指針/引用(不需要轉換,賦值兼容規則)
向下轉型:父類對象指針/引用->子類指針/引用(用dynamic_cast轉型是安全的)
注意:
1. dynamic_cast只能用于父類含有虛函數的類
2. dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回0
比如:
class A
{
public:
?? ?virtual void f() {}
};class B : public A
{};//A*指針有可能指向父類,也有可能指向子類
void fun(A* pa)
{
?? ?// dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回??? // 如果pa是指向子類,那么可以轉換,轉換表達式返回正確的地址
??? // 如果pa是指向父類,那么不能轉換,轉換表達式返回nullptr
?? ?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;
?? ?fun(&a);
?? ?fun(&b);
?? ?return 0;
}
?注意
強制類型轉換關閉或掛起了正常的類型檢查,每次使用強制類型轉換前,程序員應該仔細考慮是
否還有其他不同的方法達到同一目的,如果非強制類型轉換不可,則應限制強制轉換值的作用
域,以減少發生錯誤的機會。強烈建議:避免使用強制類型轉換。