boost.png (6897 bytes)Header boost/cast.hpp

Cast 函數

頭文件 boost/cast.hpp 提供了 polymorphic_cast polymorphic_downcast 函數模板,用於完成C++內建的轉型。

程序 cast_test.cpp 可用於檢驗這些函數模板是否正常工作。

多態轉型

指向多態對像(即定義了至少一個虛擬函數的類的對象)的指針有時需要向下轉型或交叉轉型。向下轉型是指從基類轉為派生類。交叉轉型則是指在繼承層次圖中交叉轉型,如在一個Y型層次圖中從一個基類轉為另一個基類。

這些轉型也可以用舊式的轉型來完成,但這種方式是不被推薦的。舊式轉型嚴重缺少類型安全,可讀性差,且難以用查找工具定們。

C++ 內建的 static_cast 可以用於高效地對多態對像指針進行向下轉型,但不提供錯誤檢測,無法檢測指針是否被轉型為錯誤的派生類。polymorphic_downcast 模板則在非調試編譯時保留了 static_cast 的效率,而在調試編譯時則通過 assert() 增加了 dynamic_cast 的安全性。

C++ 內建的 dynamic_cast 可用於多態對像指針的向下轉型和交叉轉型,但是以返回0值作為錯誤通告的方式使得測試不夠方便,更糟糕的是,很容易忘了測試。而 dynamic_cast 有另一種拋出異常的方式,是在使用引用時工作,在使用指針時也可通過一個難看的表達式 &dynamic_cast<T&>(*p) 來使用它,但是如果 p 為 0 則會導致未定義行為。polymorphic_cast 模板可以對指針執行 dynamic_cast,並在 dynamic_cast 返回 0 時拋出異常。

polymorphic_downcast 可在你確保成功時用於向下轉型。錯誤的檢測僅在編譯單元沒有定義 NDEBUG 時執行:

  assert( dynamic_cast<Derived>(x) == x )
其中 x 為源指針。這種方法不僅保證了返回非0指針,而且在多重繼承時也是正確的。試圖用 polymorphic_downcast 進行交叉轉型會編譯失敗。警告: 因為 polymorphic_downcast 使用了 assert(), 如果NDEBUG在編譯單元間的定義不一致,將會違犯 One Definition Rule (ODR)。 [請見 ISO Std 3.2]

對於交叉轉型,或者轉型是否成功只能在運行期才知道,或者效率不是重要的,應該首選 polymorphic_cast .

C++ 內建的 dynamic_cast 必須用於對引用轉型而不是指針。它也是唯一一個可用於檢查是否支持給定接口的轉型;這時返回0並不是錯誤的條件。

polymorphic_cast 和 polymorphic_downcast 摘要

namespace boost {

template <class Derived, class Base>
inline Derived polymorphic_cast(Base* x);
// 拋出: std::bad_cast 如果 ( dynamic_cast<Derived>(x) == 0 )
// 返回: dynamic_cast<Derived>(x)

template <class Derived, class Base>
inline Derived polymorphic_downcast(Base* x);
// 效果: assert( dynamic_cast<Derived>(x) == x );
// 返回: static_cast<Derived>(x)

}

polymorphic_downcast 示例

#include <boost/cast.hpp>
...
class Fruit { public: virtual ~Fruit(){}; ... };
class Banana : public Fruit { ... };
...
void f( Fruit * fruit ) {
// ... 我們確信 fruit 是一個 Banana
Banana * banana = boost::polymorphic_downcast<Banana*>(fruit);
...

History歷史

polymorphic_cast 由 Bjarne Stroustrup 在 "The C++ Programming Language" 中建議。
polymorphic_downcastDave Abrahams 貢獻。
舊版的 numeric_cast
Kevlin Henney 貢獻,現已被 Boost Numeric Conversion Library 取代。


Revised June 23, 2005

c Copyright boost.org 1999. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.