boost之路 十六 型別轉換操作符

2021-07-22 05:15:11 字數 4587 閱讀 4379



boost.conversion 庫由兩個檔案組成。分別在boost/cast.hpp檔案中定義了boost::polymorphic_castboost::polymorphic_downcast這兩個型別轉換操作符, 在boost/lexical_cast.hpp檔案中定義了boost::lexical_cast

boost::polymorphic_castboost::polymorphic_downcast是為了使原來用dynamic_cast實現的型別轉換更加具體。具體細節,如下例所示。

struct father 

; };

struct mother

; };

struct child :

public father,

public mother

; void func(father *f)

int main()

本例使用dynamic_cast型別轉換操作符兩次: 在func()函式中,它將指向父類的指標轉換為指向子類的指標。在main()中, 它將乙個指向父類的指標轉為指向另乙個父類的指標。第乙個轉換稱為向下轉換(downcast),第二個轉換稱為交叉轉換(cross cast)。

通過使用 boost.conversion 的型別轉換操作符,可以將向下轉換和交叉轉換區分開來。

#include struct father 

; };

struct mother

; };

struct child :

public father,

public mother

; void func(father *f)

int main()

boost::polymorphic_downcast型別轉換操作符只能用於向下轉換。 它內部使用static_cast實現型別轉換。 由於static_cast並不動態檢查型別轉換是否合法,所以boost::polymorphic_downcast應該只在型別轉換是安全的情況下使用。 在除錯(debug builds)模式下,boost::polymorphic_downcast實際上在assert ()函式中使用dynamic_cast驗證型別轉換是否合法。 請注意這種合法性檢測只在定義了ndebug巨集的情況下執行,這通常是在除錯模式下。

向下轉換最好使用boost::polymorphic_downcast, 那麼boost::polymorphic_cast就是交叉轉換所需要的了。 由於dynamic_cast是唯一能實現交叉轉換的型別轉換操作符,boost::polymorphic_cast內部使用了它。 由於boost::polymorphic_cast能夠在錯誤的時候丟擲std::bad_cast型別的異常,所以優先使用這個型別轉換操作符還是很有必要的。相反,dynamic_cast在型別轉換失敗使將返回0。 避免手工驗證返回值,boost::polymorphic_cast提供了自動化的替代方式。

boost::polymorphic_downcastboost::polymorphic_cast只在指標必須轉換的時候使用;否則,必須使用dynamic_cast執行轉換。 由於boost::polymorphic_downcast是基於static_cast,所以它不能夠,比如說,將父類物件轉換為子類物件。 如果轉換的型別不是指標,則使用boost::polymorphic_cast執行型別轉換也沒有什麼意義,而在這種情況下使用dynamic_cast還會丟擲乙個std::bad_cast異常。

雖然所有的型別轉換都可用dynamic_cast實現,可boost::polymorphic_downcastboost::polymorphic_cast也不是真正隨意使用的。 boost.conversion 還提供了另外一種在實踐中很有用的型別轉換操作符。 體會一下下面的例子。

#include #include #include int main() 

型別轉換操作符boost::lexical_cast可將數字轉換為其他型別。 例子首先將整數169轉換為字串,然後將字串轉換為浮點數。

boost::lexical_cast內部使用流(streams)執行轉換操作。 因此,只有那些過載了operator<<()operator>>()這兩個操作符的型別可以轉換。 使用boost::lexical_cast的優點是型別轉換出現在一行**之內,無需手工操作流(streams)。 由於流的用法對於型別轉換不能立刻理解**含義, 而boost::lexical_cast型別轉換操作符還可以使**更有意義,更加容易理解。

請注意boost::lexical_cast並不總是訪問流(streams);它自己也優化了一些資料型別的轉換。

如果轉換失敗,則丟擲boost::bad_lexical_cast型別的異常,它繼承自std::bad_cast

#include #include #include int main() 

catch (boost::bad_lexical_cast &e)

}

本例由於字串 "abc" 不能轉換為int型別的數字而丟擲異常。

boost.numericconversion 可將一種數值型別轉換為不同的數值型別。 在c++裡, 這種轉換可以隱式地發生,如下面例所示。

#include int main() 

由於從intshort的型別轉換自動產生,所以本例編譯沒有錯誤。 雖然本例可以執行,但結果由於依賴具體的編譯器實現而結果無法預期。 數字0x10000對於變數 i 來說太大而不能儲存在short型別的變數中。 依據c++標準,這個操作的結果是實現定義的("implementation defined")。 用visual c++ 2008編譯,應用程式顯示的是0。 s 的值當然不同於 i 的值。

為避免這種數值轉換錯誤,可以使用boost::numeric_cast型別轉換操作符。

#include #include int main() 

catch (boost::numeric::bad_numeric_cast &e)

}

boost::numeric_cast的用法與c++型別轉換操作符非常相似。 當然需要包含正確的標頭檔案;就是boost/numeric/conversion/cast.hpp

boost::numeric_cast執行與c++相同的隱式轉換操作。 但是,boost::numeric_cast驗證了在不改變量值的情況下轉換是否能夠發生。 前面給的應用例子,轉換不能發生,因而由於0x10000太大而不能儲存在short型別的變數上,而丟擲boost::numeric::bad_numeric_cast異常。

嚴格來講,丟擲的是boost::numeric::positive_overflow型別的異常,這個型別特指所謂的溢位(overflow) - 在此例中是正數。 相應地,還存在著boost::numeric::negative_overflow型別的異常,它特指負數的溢位。

#include #include int main() 

catch (boost::numeric::negative_overflow &e)

}

boost.numericconversion 還定義了其他的異常型別,都繼承自boost::numeric::bad_numeric_cast。 因為boost::numeric::bad_numeric_cast繼承自std::bad_cast,所以catch處理也可以捕獲這個型別的異常。

scala學習筆記(十六) 型別引數與隱式轉換

scala 中的型別引數晦澀難懂,不過有幾個基本要點可以記錄 t upperbound 上界,通俗理解t是 upperbound 的子類 t lowerbound 下界,通俗理解為t為 lowerbound 的超類 t comparable t 檢視界定,簡單理解為,t可以通過隱式轉換為後者 t o...

boost中型別轉換學習

型別轉換在很多時候需要使用上,方便且安全的轉換是很有必要的。從c語言的一些api到c 中提供的stringstream流都有很多方式可以實現,了解他們的特點可以讓我們在日常編碼中編寫出漂亮的 一 c語言中常用的型別轉換 char szbuf 100 int nvalue 100000000 spri...

型別轉換 數值操作

一 型別轉換函式 函式 描述 int x base 將x轉 換為乙個整數 其中base表示基數 long x base 將 x轉換為乙個長整數 float x 將 x轉換到乙個浮點數 complex real imag 建立乙個複數 str x 將 物件 x 轉換為字串 repr x 將物件 x 轉...