網(wǎng)站首頁(yè) 編程語言 正文
一、說明
Boost.Conversion 在頭文件 boost/cast.hpp 中定義了轉(zhuǎn)換運(yùn)算符 boost::polymorphic_cast 和 boost::polymorphic_downcast。它們旨在更精確地處理類型轉(zhuǎn)換——通常使用 dynamic_cast 完成。
庫(kù)由兩個(gè)文件組成。分別在boost/cast.hpp
文件中定義了boost::polymorphic_cast
和boost::polymorphic_downcast
這兩個(gè)類型轉(zhuǎn)換操作符, 在boost/lexical_cast.hpp
文件中定義了boost::lexical_cast
。
二、示例和代碼
boost::polymorphic_cast
和boost::polymorphic_downcast
是為了使原來用dynamic_cast
實(shí)現(xiàn)的類型轉(zhuǎn)換更加具體。具體細(xì)節(jié),如下例所示。
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
類型轉(zhuǎn)換操作符兩次: 在func()
函數(shù)中,它將指向父類的指針轉(zhuǎn)換為指向子類的指針。在main()
中, 它將一個(gè)指向父類的指針轉(zhuǎn)為指向另一個(gè)父類的指針。第一個(gè)轉(zhuǎn)換稱為向下轉(zhuǎn)換(downcast),第二個(gè)轉(zhuǎn)換稱為交叉轉(zhuǎn)換(cross cast)。
通過使用 Boost.Conversion 的類型轉(zhuǎn)換操作符,可以將向下轉(zhuǎn)換和交叉轉(zhuǎn)換區(qū)分開來。
#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
?類型轉(zhuǎn)換操作符只能用于向下轉(zhuǎn)換。 它內(nèi)部使用?
static_cast
?實(shí)現(xiàn)類型轉(zhuǎn)換。 由于?
static_cast
?并不動(dòng)態(tài)檢查類型轉(zhuǎn)換是否合法,所以?
boost::polymorphic_downcast
?應(yīng)該只在類型轉(zhuǎn)換是安全的情況下使用。 在調(diào)試(debug builds)模式下,?
boost::polymorphic_downcast
?實(shí)際上在?
assert ()
函數(shù)中使用
?dynamic_cast
?驗(yàn)證類型轉(zhuǎn)換是否合法。 請(qǐng)注意這種合法性檢測(cè)只在定義了
NDEBUG
宏的情況下執(zhí)行,這通常是在調(diào)試模式下。
向下轉(zhuǎn)換最好使用boost::polymorphic_downcast
, 那么boost::polymorphic_cast
就是交叉轉(zhuǎn)換所需要的了。 由于dynamic_cast
是唯一能實(shí)現(xiàn)交叉轉(zhuǎn)換的類型轉(zhuǎn)換操作符,boost::polymorphic_cast
內(nèi)部使用了它。 由于boost::polymorphic_cast
能夠在錯(cuò)誤的時(shí)候拋出std::bad_cast
類型的異常,所以優(yōu)先使用這個(gè)類型轉(zhuǎn)換操作符還是很有必要的。相反,dynamic_cast
在類型轉(zhuǎn)換失敗使將返回0。 避免手工驗(yàn)證返回值,boost::polymorphic_cast
提供了自動(dòng)化的替代方式。
boost::polymorphic_downcast
和boost::polymorphic_cast
只在指針必須轉(zhuǎn)換的時(shí)候使用;否則,必須使用dynamic_cast
執(zhí)行轉(zhuǎn)換。 由于boost::polymorphic_downcast
是基于static_cast
,所以它不能夠,比如說,將父類對(duì)象轉(zhuǎn)換為子類對(duì)象。 如果轉(zhuǎn)換的類型不是指針,則使用boost::polymorphic_cast
執(zhí)行類型轉(zhuǎn)換也沒有什么意義,而在這種情況下使用dynamic_cast
還會(huì)拋出一個(gè)std::bad_cast
異常。
雖然所有的類型轉(zhuǎn)換都可用dynamic_cast
實(shí)現(xiàn),可boost::polymorphic_downcast
和boost::polymorphic_cast
也不是真正隨意使用的。 Boost.Conversion 還提供了另外一種在實(shí)踐中很有用的類型轉(zhuǎn)換操作符。 體會(huì)一下下面的例子。
#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; }
類型轉(zhuǎn)換操作符boost::lexical_cast
可將數(shù)字轉(zhuǎn)換為其他類型。 例子首先將整數(shù)169轉(zhuǎn)換為字符串,然后將字符串轉(zhuǎn)換為浮點(diǎn)數(shù)。
boost::lexical_cast
內(nèi)部使用流(streams)執(zhí)行轉(zhuǎn)換操作。 因此,只有那些重載了operator<<()
和operator>>()
這兩個(gè)操作符的類型可以轉(zhuǎn)換。 使用boost::lexical_cast
的優(yōu)點(diǎn)是類型轉(zhuǎn)換出現(xiàn)在一行代碼之內(nèi),無需手工操作流(streams)。 由于流的用法對(duì)于類型轉(zhuǎn)換不能立刻理解代碼含義, 而boost::lexical_cast
類型轉(zhuǎn)換操作符還可以使代碼更有意義,更加容易理解。
請(qǐng)注意boost::lexical_cast
并不總是訪問流(streams);它自己也優(yōu)化了一些數(shù)據(jù)類型的轉(zhuǎn)換。
如果轉(zhuǎn)換失敗,則拋出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" 不能轉(zhuǎn)換為int
類型的數(shù)字而拋出異常。
示例 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); }
Example54.1
示例 54.1 兩次使用了轉(zhuǎn)換運(yùn)算符 dynamic_cast:在 downcast() 中,它將指向基類的指針轉(zhuǎn)換為指向派生類的指針。在 crosscast() 中,它將指向基類的指針轉(zhuǎn)換為指向不同基類的指針。第一個(gè)轉(zhuǎn)換是向下轉(zhuǎn)換,第二個(gè)轉(zhuǎn)換是交叉轉(zhuǎn)換。 Boost.Conversion 中的轉(zhuǎn)換運(yùn)算符讓您可以區(qū)分向下轉(zhuǎn)換和交叉轉(zhuǎn)換。
示例 54.2。使用 polymorphic_downcast 和 polymorphic_cast 進(jìn)行向下和交叉轉(zhuǎn)換
#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)只能用于向下轉(zhuǎn)型,因?yàn)樗褂?static_cast 來執(zhí)行轉(zhuǎn)換。因?yàn)?static_cast 不會(huì)動(dòng)態(tài)檢查轉(zhuǎn)換的有效性,boost::polymorphic_downcast 必須僅在轉(zhuǎn)換安全時(shí)使用。在調(diào)試版本中,boost::polymorphic_downcast 使用 dynamic_cast 和 assert() 來確保類型轉(zhuǎn)換有效。只有在未定義宏 NDEBUG 時(shí)才會(huì)執(zhí)行此測(cè)試,這通常是調(diào)試版本的情況。
boost::polymorphic_cast 是交叉轉(zhuǎn)換所必需的。 boost::polymorphic_cast 使用 dynamic_cast,它是唯一可以執(zhí)行交叉轉(zhuǎn)換的轉(zhuǎn)換運(yùn)算符。最好使用 boost::polymorphic_cast 而不是 dynamic_cast,因?yàn)榍罢咴诔霈F(xiàn)錯(cuò)誤時(shí)拋出 std::bad_cast 類型的異常,而 dynamic_cast 在類型轉(zhuǎn)換失敗時(shí)返回空指針。
僅使用 boost::polymorphic_downcast 和 boost::polymorphic_cast 來轉(zhuǎn)換指針;否則,使用 dynamic_cast。因?yàn)?boost::polymorphic_downcast 是基于 static_cast 的,所以它不能將基類的對(duì)象轉(zhuǎn)換為派生類的對(duì)象。此外,使用 boost::polymorphic_cast 轉(zhuǎn)換指針以外的類型沒有意義,因?yàn)槿绻D(zhuǎn)換失敗,dynamic_cast 將拋出 std::bad_cast 類型的異常。
原文鏈接:https://yamagota.blog.csdn.net/article/details/128011162
相關(guān)推薦
- 2023-06-20 Jupyter?Notebook中%time和%timeit的使用詳解_python
- 2023-02-12 C++?STL之string的模擬實(shí)現(xiàn)實(shí)例代碼_C 語言
- 2022-10-02 Redis常見限流算法原理及實(shí)現(xiàn)_Redis
- 2022-05-09 pytorch中的廣播語義_python
- 2022-09-07 如何應(yīng)用?SOLID?原則在?React?中整理代碼之開閉原則_React
- 2022-09-21 Flutter實(shí)現(xiàn)頂部導(dǎo)航欄功能_Android
- 2022-10-08 如何在React項(xiàng)目中引入字體文件并使用詳解_React
- 2022-04-02 詳解Android如何自定義view實(shí)現(xiàn)圓形進(jìn)度條_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支