<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Boost.Conversion 在標頭檔案 boost/cast.hpp 中定義了轉換運運算元 boost::polymorphic_cast 和 boost::polymorphic_downcast。它們旨在更精確地處理型別轉換——通常使用 dynamic_cast 完成。
庫由兩個檔案組成。分別在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); }
本例使用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); }
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; }
型別轉換操作符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 <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; } }
本例由於字串 "abc" 不能轉換為int
型別的數位而丟擲異常。
範例 54.1。使用 dynamic_cast 向下和交叉投射
struct base1 { virtual ~base1() = default; }; struct base2 { virtual ~base2() = default; }; struct derived : public base1, public base2 {}; void downcast(base1 *b1) { derived *d = dynamic_cast<derived*>(b1); } void crosscast(base1 *b1) { base2 *b2 = dynamic_cast<base2*>(b1); } int main() { derived *d = new derived; downcast(d); base1 *b1 = new derived; crosscast(b1); }
範例 54.1 兩次使用了轉換運運算元 dynamic_cast:在 downcast() 中,它將指向基礎類別的指標轉換為指向派生類的指標。在 crosscast() 中,它將指向基礎類別的指標轉換為指向不同基礎類別的指標。第一個轉換是向下轉換,第二個轉換是交叉轉換。 Boost.Conversion 中的轉換運運算元讓您可以區分向下轉換和交叉轉換。
範例 54.2。使用 polymorphic_downcast 和 polymorphic_cast 進行向下和交叉轉換
#include <boost/cast.hpp> struct base1 { virtual ~base1() = default; }; struct base2 { virtual ~base2() = default; }; struct derived : public base1, public base2 {}; void downcast(base1 *b1) { derived *d = boost::polymorphic_downcast<derived*>(b1); } void crosscast(base1 *b1) { base2 *b2 = boost::polymorphic_cast<base2*>(b1); } int main() { derived *d = new derived; downcast(d); base1 *b1 = new derived; crosscast(b1); }
boost::polymorphic_downcast(參見範例 54.2)只能用於向下轉型,因為它使用 static_cast 來執行轉換。因為 static_cast 不會動態檢查轉換的有效性,boost::polymorphic_downcast 必須僅在轉換安全時使用。在偵錯版本中,boost::polymorphic_downcast 使用 dynamic_cast 和 assert() 來確保型別轉換有效。只有在未定義宏 NDEBUG 時才會執行此測試,這通常是偵錯版本的情況。
boost::polymorphic_cast 是交叉轉換所必需的。 boost::polymorphic_cast 使用 dynamic_cast,它是唯一可以執行交叉轉換的轉換運運算元。最好使用 boost::polymorphic_cast 而不是 dynamic_cast,因為前者在出現錯誤時丟擲 std::bad_cast 型別的異常,而 dynamic_cast 在型別轉換失敗時返回空指標。
僅使用 boost::polymorphic_downcast 和 boost::polymorphic_cast 來轉換指標;否則,使用 dynamic_cast。因為 boost::polymorphic_downcast 是基於 static_cast 的,所以它不能將基礎類別的物件轉換為派生類的物件。此外,使用 boost::polymorphic_cast 轉換指標以外的型別沒有意義,因為如果轉換失敗,dynamic_cast 將丟擲 std::bad_cast 型別的異常。
到此這篇關於C++ Boost Conversion超詳細講解的文章就介紹到這了,更多相關C++ Boost Conversion內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45