Boost的转换函数polymorphic_cast和polymorphic_downcast

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的转换函数polymorphic_cast和polymorphic_downcast)