<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 第?16?章?類型轉換操作符 ### 目錄 * [16.1 概述](castoperators.html#castoperators_general) * [16.2 Boost.Conversion](castoperators.html#castoperators_conversion) * [16.3 Boost.NumericConversion](castoperators.html#castoperators_numeric_conversion) [![](https://box.kancloud.cn/2016-02-29_56d41c2d6e214.gif)](http://creativecommons.org/licenses/by-nc-nd/3.0/de/deed.zh) 該書采用 [Creative Commons License](http://creativecommons.org/licenses/by-nc-nd/3.0/de/deed.zh) 授權 ## 16.1.?概述 C++標準定義了四種類型轉換操作符: `static_cast`, `dynamic_cast`, `const_cast` 和 `reinterpret_cast`。 Boost.Conversion 和 Boost.NumericConversion 這兩個庫特別為某些類型轉換定義了額外的類型轉換操作符。 ## 16.2.?Boost.Conversion [Boost.Conversion](http://www.boost.org/libs/conversion/) 庫由兩個文件組成。分別在 `boost/cast.hpp` 文件中定義了 `boost::polymorphic_cast` 和 `boost::polymorphic_downcast` 這兩個類型轉換操作符, 在 `boost/lexical_cast.hpp` 文件中定義了 `boost::lexical_cast`。 `boost::polymorphic_cast` 和 `boost::polymorphic_downcast` 是為了使原來用 `dynamic_cast` 實現的類型轉換更加具體。具體細節,如下例所示。 ``` struct father { virtual ~father() { }; }; struct mother { virtual ~mother() { }; }; struct child : public father, public mother { }; void func(father *f) { child *c = dynamic_cast<child*>(f); } int main() { child *c = new child; func(c); father *f = new child; mother *m = dynamic_cast<mother*>(f); } ``` * [下載源代碼](src/16.2.1/main.cpp) 本例使用 `dynamic_cast` 類型轉換操作符兩次: 在 `func()` 函數中,它將指向父類的指針轉換為指向子類的指針。在 `main()` 中, 它將一個指向父類的指針轉為指向另一個父類的指針。第一個轉換稱為向下轉換(downcast),第二個轉換稱為交叉轉換(cross cast)。 通過使用 Boost.Conversion 的類型轉換操作符,可以將向下轉換和交叉轉換區分開來。 ``` #include <boost/cast.hpp> struct father { virtual ~father() { }; }; struct mother { virtual ~mother() { }; }; struct child : public father, public mother { }; void func(father *f) { child *c = boost::polymorphic_downcast<child*>(f); } int main() { child *c = new child; func(c); father *f = new child; mother *m = boost::polymorphic_cast<mother*>(f); } ``` * [下載源代碼](src/16.2.2/main.cpp) `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_downcast` 和 `boost::polymorphic_cast` 只在指針必須轉換的時候使用;否則,必須使用 `dynamic_cast` 執行轉換。 由于 `boost::polymorphic_downcast` 是基于 `static_cast`,所以它不能夠,比如說,將父類對象轉換為子類對象。 如果轉換的類型不是指針,則使用 `boost::polymorphic_cast` 執行類型轉換也沒有什么意義,而在這種情況下使用 `dynamic_cast` 還會拋出一個 `std::bad_cast` 異常。 雖然所有的類型轉換都可用 `dynamic_cast` 實現,可 `boost::polymorphic_downcast` 和 `boost::polymorphic_cast` 也不是真正隨意使用的。 Boost.Conversion 還提供了另外一種在實踐中很有用的類型轉換操作符。 體會一下下面的例子。 ``` #include <boost/lexical_cast.hpp> #include <string> #include <iostream> int main() { std::string s = boost::lexical_cast<std::string>(169); std::cout << s << std::endl; double d = boost::lexical_cast<double>(s); std::cout << d << std::endl; } ``` * [下載源代碼](src/16.2.3/main.cpp) 類型轉換操作符 `boost::lexical_cast` 可將數字轉換為其他類型。 例子首先將整數169轉換為字符串,然后將字符串轉換為浮點數。 `boost::lexical_cast` 內部使用流(streams)執行轉換操作。 因此,只有那些重載了 `operator&lt;&lt;()` 和 `operator&gt;&gt;()` 這兩個操作符的類型可以轉換。 使用 `boost::lexical_cast` 的優點是類型轉換出現在一行代碼之內,無需手工操作流(streams)。 由于流的用法對于類型轉換不能立刻理解代碼含義, 而 `boost::lexical_cast` 類型轉換操作符還可以使代碼更有意義,更加容易理解。 請注意 `boost::lexical_cast` 并不總是訪問流(streams);它自己也優化了一些數據類型的轉換。 如果轉換失敗,則拋出 `boost::bad_lexical_cast` 類型的異常,它繼承自 `std::bad_cast`。 ``` #include <boost/lexical_cast.hpp> #include <string> #include <iostream> int main() { try { int i = boost::lexical_cast<int>("abc"); std::cout << i << std::endl; } catch (boost::bad_lexical_cast &e) { std::cerr << e.what() << std::endl; } } ``` * [下載源代碼](src/16.2.4/main.cpp) 本例由于字符串 "abc" 不能轉換為 `int` 類型的數字而拋出異常。 ## 16.3.?Boost.NumericConversion [Boost.NumericConversion](http://www.boost.org/libs/numeric/conversion/) 可將一種數值類型轉換為不同的數值類型。 在C++里, 這種轉換可以隱式地發生,如下面例所示。 ``` #include <iostream> int main() { int i = 0x10000; short s = i; std::cout << s << std::endl; } ``` * [下載源代碼](src/16.3.1/main.cpp) 由于從 `int` 到 `short` 的類型轉換自動產生,所以本例編譯沒有錯誤。 雖然本例可以運行,但結果由于依賴具體的編譯器實現而結果無法預期。 數字`0x10000`對于變量 `i` 來說太大而不能存儲在 `short` 類型的變量中。 依據C++標準,這個操作的結果是實現定義的("implementation defined")。 用Visual C++ 2008編譯,應用程序顯示的是`0`。 `s` 的值當然不同于 `i` 的值。 為避免這種數值轉換錯誤,可以使用 `boost::numeric_cast` 類型轉換操作符。 ``` #include <boost/numeric/conversion/cast.hpp> #include <iostream> int main() { try { int i = 0x10000; short s = boost::numeric_cast<short>(i); std::cout << s << std::endl; } catch (boost::numeric::bad_numeric_cast &e) { std::cerr << e.what() << std::endl; } } ``` * [下載源代碼](src/16.3.2/main.cpp) `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 <boost/numeric/conversion/cast.hpp> #include <iostream> int main() { try { int i = -0x10000; short s = boost::numeric_cast<short>(i); std::cout << s << std::endl; } catch (boost::numeric::negative_overflow &e) { std::cerr << e.what() << std::endl; } } ``` * [下載源代碼](src/16.3.3/main.cpp) Boost.NumericConversion 還定義了其他的異常類型,都繼承自 `boost::numeric::bad_numeric_cast`。 因為 `boost::numeric::bad_numeric_cast` 繼承自 `std::bad_cast`,所以 `catch` 處理也可以捕獲這個類型的異常。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看