C++ static_cast dynamic_cast const_cast reinterpret_cast使用总结
生活随笔
收集整理的這篇文章主要介紹了
C++ static_cast dynamic_cast const_cast reinterpret_cast使用总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
因為原來C風格的暴力萬能類型轉換容易導致運行時出錯,所以要引入分類更清晰提前發現錯誤的轉換語法。
對象的類型轉換包含了對象的引用或指針。
1.static_cast是編譯器默認選項,該運算符把expression轉換為type-id類型,但沒有運行時類型檢查來保證轉換的安全性。
但是沒有動態檢查所以類對象間非直線繼承轉換不支持(無關對象指針類型),C風格的轉換確是可以的,所以并不是C風格轉換的替代品。
所以基本類型轉換,類上行轉換(類的下行轉換有隱患),把其它類型轉換為void*都是安全的(void*轉換為目標類型就要小心了)。
2.dynamic_cast是動態類型轉換提前檢查: 該運算符把expression轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void*。
1)下行轉換,兄弟之間轉換,動態實例到當前指針非直線繼承轉換 如果不安全(父實例不能下行,兄弟實例不能相互轉換),那么會提前得到空指針。 如果安全,那么下行轉換和對象間非直線繼承轉換(包括上行)還需要有虛函數,才支持動態轉換(實例合理則不為空),一般繼承中都用虛析構函數故基本是沒問題的。 2).上行轉換和多繼承情況: 多繼承中,多條路徑時候需要多次dynamic_cast指定以表明用具體路徑進行轉換。
3.const_cast一般將常量轉換為非常量指針,用非常量指針對數據進行修改。該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的類型是一樣的。
4.reinterpret_cast是將一種類型無位損失的轉換為另一種類型例如字符串轉換為整型,他們的內存結構會是一樣的,也可以把一種類型轉換為*void再由于*void轉換回該類型。 type-id 必須是一個指針、引用、算術類型、函數指針或者成員指針。它可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,在把該整數轉換成原類型的指針,還可以得到原先的指針值)。
特別是開辟了系統全局的內存空間,需要在多個應用程序之間使用時,需要彼此共享,傳遞這個內存空間的指針時,就可以將指針轉換成整數值,得到以后,再將整數值轉換成指針,進行對應的操作。
測試實例: class A { public: int a; A() { a = 0; } virtual void display() { cout<< "I am A"<<endl; } virtual ~A() { } };
class AImpl: public A { public: int b; AImpl() { b = 0; } virtual void display() { cout<< "I am AImpl"<<endl; } virtual ~AImpl() { } };
class B: public AImpl { public: int b; B() { b = 0; } virtual void display() { cout<< "I am B"<<endl; } virtual ~B() { } };
class C:public AImpl { public: int a; C() { a = 0; } virtual void display() { cout<< "I am C"<<endl; } virtual ~C() { } };
class D: public B,public C { virtual void display() { cout<< "I am D"<<endl; } };
int main( int argc, char *argv[] ) { D *d = new D(); B *b =dynamic_cast<B*>(d); A *a = dynamic_cast<A*>(b); AImpl *aimp= dynamic_cast<AImpl*>(a); aimp->display(); }
reference: http://www.cplusplus.com/doc/tutorial/typecasting/ https://msdn.microsoft.com/en-us/library/cby9kycs
2.dynamic_cast是動態類型轉換提前檢查: 該運算符把expression轉換成type-id類型的對象。Type-id必須是類的指針、類的引用或者void*。
1)下行轉換,兄弟之間轉換,動態實例到當前指針非直線繼承轉換 如果不安全(父實例不能下行,兄弟實例不能相互轉換),那么會提前得到空指針。 如果安全,那么下行轉換和對象間非直線繼承轉換(包括上行)還需要有虛函數,才支持動態轉換(實例合理則不為空),一般繼承中都用虛析構函數故基本是沒問題的。 2).上行轉換和多繼承情況: 多繼承中,多條路徑時候需要多次dynamic_cast指定以表明用具體路徑進行轉換。
3.const_cast一般將常量轉換為非常量指針,用非常量指針對數據進行修改。該運算符用來修改類型的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的類型是一樣的。
4.reinterpret_cast是將一種類型無位損失的轉換為另一種類型例如字符串轉換為整型,他們的內存結構會是一樣的,也可以把一種類型轉換為*void再由于*void轉換回該類型。 type-id 必須是一個指針、引用、算術類型、函數指針或者成員指針。它可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,在把該整數轉換成原類型的指針,還可以得到原先的指針值)。
特別是開辟了系統全局的內存空間,需要在多個應用程序之間使用時,需要彼此共享,傳遞這個內存空間的指針時,就可以將指針轉換成整數值,得到以后,再將整數值轉換成指針,進行對應的操作。
測試實例: class A { public: int a; A() { a = 0; } virtual void display() { cout<< "I am A"<<endl; } virtual ~A() { } };
class AImpl: public A { public: int b; AImpl() { b = 0; } virtual void display() { cout<< "I am AImpl"<<endl; } virtual ~AImpl() { } };
class B: public AImpl { public: int b; B() { b = 0; } virtual void display() { cout<< "I am B"<<endl; } virtual ~B() { } };
class C:public AImpl { public: int a; C() { a = 0; } virtual void display() { cout<< "I am C"<<endl; } virtual ~C() { } };
class D: public B,public C { virtual void display() { cout<< "I am D"<<endl; } };
int main( int argc, char *argv[] ) { D *d = new D(); B *b =dynamic_cast<B*>(d); A *a = dynamic_cast<A*>(b); AImpl *aimp= dynamic_cast<AImpl*>(a); aimp->display(); }
reference: http://www.cplusplus.com/doc/tutorial/typecasting/ https://msdn.microsoft.com/en-us/library/cby9kycs
總結
以上是生活随笔為你收集整理的C++ static_cast dynamic_cast const_cast reinterpret_cast使用总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dapper.NET——轻量ORM
- 下一篇: SQL ORDER BY 两个列