亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

polymorphic_cast

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

Boost的polymorphic_cast在dynamic_cast的基礎(chǔ)上增加了對返回值的檢測,如果轉(zhuǎn)換失敗,它就會拋出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;
}

雖然拋異常增加了開銷,但使用起來卻更加簡單了。

polymorphic_downcast

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

對于上述程序,雖然pa和pb間沒有繼承關(guān)系,但是這個轉(zhuǎn)換卻可以通過,運行時也不會報任何錯誤,可一旦對pb進行訪問,就會得到錯誤的結(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);
}

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

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

boost::numeric_cast

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

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

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

boost::numeric_cast可以幫助我們解決這一問題,對于上面的轉(zhuǎn)換,boost::numeric_cast會拋出一個boost:: bad_numeric_cast這個異常對象。從而保證轉(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。當然也可以將自己定義的數(shù)字抽象類型添加到std::numeric_limits<>的特化版本中,這樣numeric_cast就可以作用于自定義的類型了。由于相對復(fù)雜點,本文是介紹其功能和用法,就不分析其源碼了,感興趣的朋友可以參看boost文檔和代碼。

對于numeric_cast的使用也是有些要求的。

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

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

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

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

boost::lexical_cast

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

#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)換中,第二個轉(zhuǎn)換從"err"到int的轉(zhuǎn)換是失敗的,會拋出一個boost::bad_lexical_cast的異常,從而能幫助我們構(gòu)造更安全穩(wěn)定的程序。

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

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<>對字符串流做了一系列的包裝,主要提供了operator<<(Source)和operator>>(Target)操作,用于判斷操作是否成功。

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

相關(guān)文章

  • 簡明的C++函數(shù)指針學(xué)習教程

    簡明的C++函數(shù)指針學(xué)習教程

    這篇文章主要介紹了C++函數(shù)指針的學(xué)習教程,講到了函數(shù)指針的定義及把指針作為函數(shù)參數(shù)進行傳遞的用法,需要的朋友可以參考下
    2016-04-04
  • c++和python實現(xiàn)順序查找實例

    c++和python實現(xiàn)順序查找實例

    這篇文章主要介紹了c++和python實現(xiàn)順序查找實例,流程即將目標數(shù)值和數(shù)據(jù)庫中的每個數(shù)值進行比較,如果相同則搜索完成,如果不同則繼續(xù)比較下一處,下面來看看具體的實例操作吧,需要的朋友可以參考一下
    2022-03-03
  • 使用Qt實現(xiàn)監(jiān)聽網(wǎng)頁是否響應(yīng)并導(dǎo)出Excel表

    使用Qt實現(xiàn)監(jiān)聽網(wǎng)頁是否響應(yīng)并導(dǎo)出Excel表

    Qt導(dǎo)出數(shù)據(jù)到excel,方法有很多,下面這篇文章主要給大家介紹了關(guān)于使用Qt實現(xiàn)監(jiān)聽網(wǎng)頁是否響應(yīng)并導(dǎo)出Excel表的相關(guān)資料,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • 詳解Visual Studio 2019(VS2019) 基本操作

    詳解Visual Studio 2019(VS2019) 基本操作

    這篇文章主要介紹了詳解Visual Studio 2019(VS2019) 基本操作,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧
    2020-03-03
  • C++實現(xiàn)插入排序?qū)φ麛?shù)數(shù)組排序

    C++實現(xiàn)插入排序?qū)φ麛?shù)數(shù)組排序

    這篇文章主要為大家詳細介紹了C++實現(xiàn)插入排序?qū)φ麛?shù)數(shù)組排序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C++騎士游歷問題(馬踏棋盤)解析

    C++騎士游歷問題(馬踏棋盤)解析

    這篇文章主要為大家詳細介紹了C++騎士游歷問題的解答思路,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C語言動態(tài)內(nèi)存函數(shù)(malloc、calloc、realloc、free)詳解

    C語言動態(tài)內(nèi)存函數(shù)(malloc、calloc、realloc、free)詳解

    在C語言中,動態(tài)內(nèi)存函數(shù)是塊重要的知識點,以往,我們開辟空間都是固定得,數(shù)組編譯結(jié)束后就不能繼續(xù)給它開辟空間了,開辟的空間滿了,就不能在開辟空間了,學(xué)習本文章,我們就可以解決這個問題,向內(nèi)存申請空間,感興趣的小伙伴跟著小編一起來看看吧
    2023-08-08
  • C語言深入淺出講解順序表的實現(xiàn)

    C語言深入淺出講解順序表的實現(xiàn)

    線性表是最簡單的數(shù)據(jù)結(jié)構(gòu),而順序表又是最簡單的線性表,其基本思想是用一段地址連續(xù)的儲存單元依次存儲線性表的數(shù)據(jù)元素,比如我們常用的一維數(shù)組,下面代碼實現(xiàn)了順序表的定義以及基本操作
    2022-04-04
  • 用C++實現(xiàn)推箱子小游戲

    用C++實現(xiàn)推箱子小游戲

    這篇文章主要為大家詳細介紹了用C++實現(xiàn)推箱子小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C++實現(xiàn)ini文件讀寫的示例代碼

    C++實現(xiàn)ini文件讀寫的示例代碼

    這篇文章主要介紹了C++如何實現(xiàn)讀寫ini配置文件,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2022-05-05

最新評論