Boost的轉換函式(一)

來源:互聯網
上載者:User

原文地址:http://www.cnblogs.com/TianFang/archive/2008/09/24/1298344.html

Boost的轉換函式(一)

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

  • polymorphic_cast

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

Boost的polymorphic_cast在dynamic_cast的基礎上增加了對傳回值的檢測,如果轉換失敗,它就會拋出std::bad_cast異常。其函數體如下:

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結構來確定正確的類型,所以不管是空間上的成本還是時間上的成本,都會大大增加。在一些應用情境中,只需要在編譯期間進行類型轉換即可。這時我們可以使用static_cast來實現編譯期間的類型轉換,但static_cast可能導致錯誤的類型轉換:

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間沒有繼承關係,但是這個轉換卻可以通過,運行時也不會報任何錯誤,可一旦對pb進行訪問,就會得到錯誤的結果甚至直接導致程式死掉。

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模式下,它會首先進行一次動態轉換,而一旦類型不符,就會拋出異常。

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

  

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

  • polymorphic_cast

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

Boost的polymorphic_cast在dynamic_cast的基礎上增加了對傳回值的檢測,如果轉換失敗,它就會拋出std::bad_cast異常。其函數體如下:

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結構來確定正確的類型,所以不管是空間上的成本還是時間上的成本,都會大大增加。在一些應用情境中,只需要在編譯期間進行類型轉換即可。這時我們可以使用static_cast來實現編譯期間的類型轉換,但static_cast可能導致錯誤的類型轉換:

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間沒有繼承關係,但是這個轉換卻可以通過,運行時也不會報任何錯誤,可一旦對pb進行訪問,就會得到錯誤的結果甚至直接導致程式死掉。

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模式下,它會首先進行一次動態轉換,而一旦類型不符,就會拋出異常。

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

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.