最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中Boost的轉(zhuǎn)換函數(shù)

 更新時(shí)間:2022年06月16日 10:19:44   作者:天方  
這篇文章介紹了C++中Boost的轉(zhuǎn)換函數(shù),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Boost的轉(zhuǎn)換函數(shù)是對(duì)C++中的四種類型轉(zhuǎn)換函數(shù)(const_cast,reinterpret_cast,static_cast,dynamic_cast)的一些補(bǔ)充和擴(kuò)展,在閱讀本文前,請(qǐng)先熟悉C++中的四種類型轉(zhuǎn)換函數(shù)相關(guān)知識(shí)。

polymorphic_cast

C++提供了dynamic_cast來(lái)實(shí)現(xiàn)運(yùn)行時(shí)的類型轉(zhuǎn)換,但是如果用來(lái)轉(zhuǎn)換指針時(shí),需要記得檢查返回值(這是很多程序員容易忘掉的地方),否則一旦轉(zhuǎn)換失敗,將獲得一個(gè)NULL指針,無(wú)異于給程序埋下了一個(gè)定時(shí)炸彈。

Boost的polymorphic_cast在dynamic_cast的基礎(chǔ)上增加了對(duì)返回值的檢測(cè),如果轉(zhuǎn)換失敗,它就會(huì)拋出std::bad_cast異常。其函數(shù)體如下:

template <class Target, class Source>
inline Target polymorphic_cast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
{
    Target tmp = dynamic_cast<Target>(x);
    if ( tmp == 0 ) throw std::bad_cast();
    return tmp;
}

雖然拋異常增加了開銷,但使用起來(lái)卻更加簡(jiǎn)單了。

polymorphic_downcast

由于拋出異常會(huì)降低程序的效率,而且dynamic_cast更會(huì)查詢一個(gè)type_info結(jié)構(gòu)來(lái)確定正確的類型,所以不管是空間上的成本還是時(shí)間上的成本,都會(huì)大大增加。在一些應(yīng)用場(chǎng)景中,只需要在編譯期間進(jìn)行類型轉(zhuǎn)換即可。這時(shí)我們可以使用static_cast來(lái)實(shí)現(xiàn)編譯期間的類型轉(zhuǎn)換,但static_cast可能導(dǎo)致錯(cuò)誤的類型轉(zhuǎn)換:

struct A
{
    virtual ~A(){}
};

class B:public A{};
class C:public A{};

int main()
{
    A *pa = new C();
    B *pb = static_cast<B*>(pa);
}

對(duì)于上述程序,雖然pa和pb間沒有繼承關(guān)系,但是這個(gè)轉(zhuǎn)換卻可以通過(guò),運(yùn)行時(shí)也不會(huì)報(bào)任何錯(cuò)誤,可一旦對(duì)pb進(jìn)行訪問,就會(huì)得到錯(cuò)誤的結(jié)果甚至直接導(dǎo)致程序死掉。

polymorphic_downcast就巧妙的解決的這一問題,首先還是先看看它的定義:

template <class Target, class Source>
inline Target polymorphic_downcast(Source* x BOOST_EXPLICIT_DEFAULT_TARGET)
{
    BOOST_ASSERT( dynamic_cast<Target>(x) == x ); // detect logic error
    return static_cast<Target>(x);
}

從它的定義可以看出,在運(yùn)行Release模式下,它和是static_cast一樣的,也就是說(shuō)它的Release版具有和static_cast一樣的開銷。但在Debug模式下,它會(huì)首先進(jìn)行一次動(dòng)態(tài)轉(zhuǎn)換,而一旦類型不匹配,就會(huì)拋出異常。

在上述程序中,如果用polymorphic_downcast來(lái)替換static_cast的話,我們可以先在Debug模式下運(yùn)行程序,如果有錯(cuò)誤的類型轉(zhuǎn)換,將很容易的檢測(cè)出來(lái)。待改正所有的錯(cuò)誤后,再發(fā)布Release版,這樣即沒有動(dòng)態(tài)轉(zhuǎn)換造成的開銷,又杜絕了錯(cuò)誤的類型轉(zhuǎn)換。

boost::numeric_cast

在c++中,我們經(jīng)常需要把不同類型的數(shù)字互相轉(zhuǎn)換,如將一個(gè)數(shù)字在long和short之間轉(zhuǎn)換。但由于各數(shù)字的精度不同,當(dāng)一個(gè)數(shù)字從"大"類型到"小"類型就可能導(dǎo)致轉(zhuǎn)換失敗,如下所示:

long n1 = 99999999;
short n2 = static_cast<short>(n1);

對(duì)于如上轉(zhuǎn)換,n2得到的是一個(gè)負(fù)數(shù),顯然這個(gè)不是我們所期望的,并且這種運(yùn)行時(shí)的錯(cuò)誤是很難檢測(cè)的,一旦使用了這個(gè)錯(cuò)誤的轉(zhuǎn)換后的數(shù)據(jù),后果不堪設(shè)想。

boost::numeric_cast可以幫助我們解決這一問題,對(duì)于上面的轉(zhuǎn)換,boost::numeric_cast會(huì)拋出一個(gè)boost:: bad_numeric_cast這個(gè)異常對(duì)象。從而保證轉(zhuǎn)換后值的有效性。上述代碼可以改寫為如下:

try
{
    long n1 = 99999999;
    short n2 = boost::numeric_cast<short>(n1);
}
catch(boost::bad_numeric_cast&)
{
    std::cout<<"The conversion failed"<<std::endl;
}

numeric_cast是如何知道這樣的數(shù)字轉(zhuǎn)換失敗的呢?numeric_cast合理的應(yīng)用了std::numeric_limits<>,而std::numeric_limits<>就是內(nèi)建數(shù)字類型的type_tratis。當(dāng)然也可以將自己定義的數(shù)字抽象類型添加到std::numeric_limits<>的特化版本中,這樣numeric_cast就可以作用于自定義的類型了。由于相對(duì)復(fù)雜點(diǎn),本文是介紹其功能和用法,就不分析其源碼了,感興趣的朋友可以參看boost文檔和代碼。

對(duì)于numeric_cast的使用也是有些要求的。

  • 源類型和目標(biāo)類型必須都是可拷貝構(gòu)造的

  • 源類型和目標(biāo)類型必須都是數(shù)字型類型。也就是被std::numeric_limits<>::is_specialized的特化定義為true

  • 源類型必須能被static_cast轉(zhuǎn)換為目標(biāo)類型

其實(shí)對(duì)我們用的系統(tǒng)內(nèi)置的數(shù)字來(lái)說(shuō),這幾條都不是限制,只有我們?cè)谛枰ㄟ^(guò)它轉(zhuǎn)換自定義的數(shù)據(jù)類型時(shí),才需要注意,否則編譯不通過(guò)(其實(shí)這個(gè)錯(cuò)誤還比較好發(fā)現(xiàn)和解決)。

boost::lexical_cast

在C/C++程序開發(fā)中,往往需要將數(shù)字型對(duì)象的值轉(zhuǎn)換為字符文本格式,或反之操作。雖然C語(yǔ)言就提供了不少系統(tǒng)函數(shù)來(lái)進(jìn)行這種操作,如scanf、atoi等。這些函數(shù)小巧簡(jiǎn)潔,使用很方便,但缺少擴(kuò)展性。在std中引入了stringstream來(lái)以一個(gè)通用的方式實(shí)現(xiàn)各種轉(zhuǎn)換,但缺少對(duì)錯(cuò)誤轉(zhuǎn)換的檢測(cè)。而boost::lexical_cast是在stringstream上的一個(gè)擴(kuò)展,增加了對(duì)錯(cuò)誤的類型轉(zhuǎn)換的檢測(cè):

#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>

using namespace std;

int main()
{     
    try
    {
        int i = 100;
        string str = boost::lexical_cast<string>(i);
        cout<<"The string is:"<<str<<endl;
        str = "error";
        i = boost::lexical_cast<int>(str);
    }
    catch(boost::bad_lexical_cast& exobj)
    {
        cout<<"Convert err:"<<endl;
        cout<<exobj.what()<<endl;
    }
}

在上述轉(zhuǎn)換中,第二個(gè)轉(zhuǎn)換從"err"到int的轉(zhuǎn)換是失敗的,會(huì)拋出一個(gè)boost::bad_lexical_cast的異常,從而能幫助我們構(gòu)造更安全穩(wěn)定的程序。

boost::lexical_cast內(nèi)部實(shí)現(xiàn)其實(shí)也是一個(gè)stringstream的封裝,其函數(shù)簡(jiǎn)化如下:

template<typename Target,typename Source>
Target lexical_cast(Source arg){
    detail::lexical_stream<Target,Source> interpreter;
    Target result;
    if(!(interpreter<<arg && interpreter>>result))
        throw_exception(bad_lexical_cast(typeid(Target),typeid(Source)));
    return result;
}

其中l(wèi)exical_stream<>對(duì)字符串流做了一系列的包裝,主要提供了operator<<(Source)和operator>>(Target)操作,用于判斷操作是否成功。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++處理輸入字符串并轉(zhuǎn)為數(shù)組的操作

    C++處理輸入字符串并轉(zhuǎn)為數(shù)組的操作

    這篇文章主要介紹了C++處理輸入字符串并轉(zhuǎn)為數(shù)組的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • C/C++ 讀取16進(jìn)制文件的方法

    C/C++ 讀取16進(jìn)制文件的方法

    下面小編就為大家?guī)?lái)一篇C/C++ 讀取16進(jìn)制文件的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • 淺析如何在c語(yǔ)言中調(diào)用Linux腳本

    淺析如何在c語(yǔ)言中調(diào)用Linux腳本

    如何在c語(yǔ)言中調(diào)用Linux腳本呢?下面小編就為大家詳細(xì)的介紹一下吧!需要的朋友可以過(guò)來(lái)參考下
    2013-08-08
  • VC定時(shí)器的用法實(shí)例詳解

    VC定時(shí)器的用法實(shí)例詳解

    這篇文章主要介紹了VC定時(shí)器的用法,以實(shí)例形式詳細(xì)講述了VC定時(shí)器的原理與具體用法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-10-10
  • C語(yǔ)言修煉之路函數(shù)篇真題訓(xùn)練下

    C語(yǔ)言修煉之路函數(shù)篇真題訓(xùn)練下

    函數(shù)是一組一起執(zhí)行一個(gè)任務(wù)的語(yǔ)句。每個(gè) C 程序都至少有一個(gè)函數(shù),即主函數(shù) main() ,所有簡(jiǎn)單的程序都可以定義其他額外的函數(shù)
    2022-03-03
  • C++中求余運(yùn)算符(%)示例詳解

    C++中求余運(yùn)算符(%)示例詳解

    求余運(yùn)算符“%”,二元運(yùn)算符,具有左結(jié)合性。參與運(yùn)算的量均為整型。求余運(yùn)算的結(jié)果等于兩個(gè)數(shù)相除后的余數(shù)??此坪芎?jiǎn)單的運(yùn)算符,卻也真要掌握用好它也不容易,這篇文章主要介紹了C++中求余運(yùn)算符(%)的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-01-01
  • c++ base64編解碼使用示例

    c++ base64編解碼使用示例

    這篇文章主要介紹了c++的base64編解碼使用示例,需要的朋友可以參考下
    2014-02-02
  • 深入理解C語(yǔ)言指針及占據(jù)內(nèi)存空間

    深入理解C語(yǔ)言指針及占據(jù)內(nèi)存空間

    這篇文章主要介紹了C語(yǔ)言指針及占據(jù)內(nèi)存空間的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Microsoft Visual C++ 安裝失敗 0x80070666的問題解決

    Microsoft Visual C++ 安裝失敗 0x80070666的問題解

    本文主要介紹了Microsoft Visual C++ 安裝失敗 0x80070666的問題解決,錯(cuò)誤可能由已安裝其他VisualC++版本、VisualC++安裝異常、Windows更新計(jì)劃安裝同一VisualC++包等原因引起,下面就來(lái)介紹一下解決方案,感興趣的可以了解一下
    2025-03-03
  • 基于C++語(yǔ)言實(shí)現(xiàn)機(jī)動(dòng)車違章處罰管理系統(tǒng)

    基于C++語(yǔ)言實(shí)現(xiàn)機(jī)動(dòng)車違章處罰管理系統(tǒng)

    這篇文章主要介紹了基于C++語(yǔ)言實(shí)現(xiàn)機(jī)動(dòng)車違章處罰管理系統(tǒng)的相關(guān)資料,需要的朋友可以參考下
    2016-07-07

最新評(píng)論

新河县| 龙岩市| 甘德县| 黄大仙区| 连江县| 灌南县| 吉隆县| 绥宁县| 武清区| 仪征市| 石狮市| 宁津县| 石屏县| 正宁县| 德州市| 安国市| 黔东| 和林格尔县| 黄平县| 乌拉特后旗| 连山| 永定县| 乡宁县| 隆德县| 井研县| 永胜县| 江西省| 庆城县| 常熟市| 伽师县| 二连浩特市| 平潭县| 湄潭县| 准格尔旗| 左贡县| 安福县| 鹤壁市| 城口县| 临城县| 锡林郭勒盟| 射洪县|