boost::polymorphic_cast
和 boost::polymorphic_downcast
是为了使原来用 dynamic_cast
实现的类型转换更加具体。具体细节,如下例所示。
本例使用 dynamic_cast
类型转换操作符两次: 在 func()
函数中,它将指向父类的指针转换为指向子类的指针。在 main()
中, 它将一个指向父类的指针转为指向另一个父类的指针。第一个转换称为向下转换(downcast),第二个转换称为交叉转换(cross cast)。
通过使用 Boost.Conversion 的类型转换操作符,可以将向下转换和交叉转换区分开来。
向下转换最好使用 boost::polymorphic_downcast
, 那么 boost::polymorphic_cast
就是交叉转换所需要的了。 由于 dynamic_cast
是唯一能实现交叉转换的类型转换操作符,boost::polymorphic_cast
内部使用了它。 由于 boost::polymorphic_cast
能够在错误的时候抛出 std::bad_cast
类型的异常,所以优先使用这个类型转换操作符还是很有必要的。相反,dynamic_cast
在类型转换失败使将返回0。 避免手工验证返回值,boost::polymorphic_cast
提供了自动化的替代方式。
boost::polymorphic_downcast
和 boost::polymorphic_cast
只在指针必须转换的时候使用;否则,必须使用 dynamic_cast
执行转换。 由于 boost::polymorphic_downcast
是基于 static_cast
,所以它不能够,比如说,将父类对象转换为子类对象。 如果转换的类型不是指针,则使用 执行类型转换也没有什么意义,而在这种情况下使用 dynamic_cast
还会抛出一个 std::bad_cast
异常。
虽然所有的类型转换都可用 dynamic_cast
实现,可 boost::polymorphic_downcast
和 boost::polymorphic_cast
也不是真正随意使用的。 Boost.Conversion 还提供了另外一种在实践中很有用的类型转换操作符。 体会一下下面的例子。
boost::lexical_cast
内部使用流(streams)执行转换操作。 因此,只有那些重载了 operator<<()
和 operator>>()
这两个操作符的类型可以转换。 使用 boost::lexical_cast
的优点是类型转换出现在一行代码之内,无需手工操作流(streams)。 由于流的用法对于类型转换不能立刻理解代码含义, 而 boost::lexical_cast
类型转换操作符还可以使代码更有意义,更加容易理解。
请注意 boost::lexical_cast
并不总是访问流(streams);它自己也优化了一些数据类型的转换。
如果转换失败,则抛出 boost::bad_lexical_cast
类型的异常,它继承自 std::bad_cast
。