標籤:
C++風格的四種類型轉換方法:static_cast、dynamic_cast、reinterpret_cast、const_cast。
歡迎來到 lovickie 的部落格 http://www.cnblogs.com/lovickie
使用 static_cast 可以進行接近C風格的靜態轉換,但增加了安全性考慮。
double d = 3.14;int i = static_cast<int> (d);
歡迎來到 lovickie 的部落格 http://www.cnblogs.com/lovickie
上行轉換(子類指標轉父類指標)一般是安全的,當然必須得 public 繼承才合法。下行轉換(父類指標轉子類指標)很可能不安全(例如當指標指向父類對象時)。
可以採用 dynamic_cast<type> (expression) 動態轉換的條件是:type為指標或引用,下行轉換時基類為多態(有虛函數,從而可以在虛表中放一個類型資訊指標—— dynamic_cast 的一種典型實現)。對於不安全的指標下行轉換,dynamic_cast 返回 NULL。
class Dad {};class Son: public Dad{public: void func ();};int main (){ Dad d; Son *s1 = (Son*) &d; // 編譯通過 s1->func (); // 運行出錯 Son *s2 = static_cast<Son*> (&d); // 編譯報錯: 無法轉換 s2->func (); Son *s3 = dynamic_cast<Son*> (&d); // 編譯報錯: Dad不是多態類型, 除非Dad中有虛函數}
class Dad{ virtual void func ();};class Son: public Dad {};int main (){ Son son; Dad *pd = dynamic_cast<Dad*> (&son); // 上行轉換, ok Dad dad; Son *ps = dynamic_cast<Son*> (&dad); // 下行轉換, ps=0 Dad *pdad = new Dad, *pson = new Son; ps = dynamic_cast<Son*> (pdad); // 下行轉換, ps=0 ps = dynamic_cast<Son*> (pson); // 下行轉換, ok}
如上面這個例子所示,對指標下行轉換時,如果失敗 dynamic_cast 會返回0;而對引用下行轉換時,如果失敗會拋出 bad_cast 異常。
void f (Dad &dad){ try { Son &son = dynamic_cast<Son&> (dad); } catch ( bad_cast ) { // 異常處理 }}
當轉換源指標或目標指標為 void * 時,dynamic_cast 總認為安全。目標指標為 void * 可以用於確定多態類型的對象的起始地址。
class A{ virtual void func ();};int main (){ A *a = new A; void *v = dynamic_cast<void*> (a); // 同樣要求A多態 a = dynamic_cast<A*> (v);}
和 typeid 一樣,dynamic_cast 使用了“運行時類型資訊” RTTI(Run Time Type Information),某些平台可能不支援。
歡迎來到 lovickie 的部落格 http://www.cnblogs.com/lovickie
使用 reinterpret_cast<type> (expression) 可以在指標之間或指標與整數之間轉換類型,同樣要求 type 為指標或引用。
int *p = new int;long i = reinterpret_cast<long> (p);p = 0; // p 不再指向 new intp = reinterpret_cast<int*> i; // p 重新指向 new int
歡迎來到 lovickie 的部落格 http://www.cnblogs.com/lovickie
使用 const_cast 可以將常量轉換為變數,去除 const 屬性。
const char *str = "hello";char *s = const_cast<char*> (str);
在類 A 的 const 成員函數中,如果想要修改 A 的成員變數,可以先將 this 強制去除 const 屬性。但當對象本身就是常量時,結果將不可預見。
class A{ bool m;public: void func () const { A *a = const_cast<A*> (this); // 強制去除const屬性 a->m = true; }};int main (){ A a1; const A a2; a1.func (); // ok a2.func (); // 無定義行為}
因此,令某些成員變數可被 const 成員函數修改的更好的解決方案是,將成員變數聲明為 mutable,或者將這些成員變數封裝到結構體指標中。
歡迎來到 lovickie 的部落格 http://www.cnblogs.com/lovickie
無。
【C++】類型轉換