一个命名的强制类型转换具有如下形式:
cast-name<type>(expression);
其中,type是转换的目标类型而expression是要转换的值。如果type是引用类型,则结果是左值(左值是指一个在内存中占有确定位置的对象,即是有一个地址)。cast-name是static_cast、dynamic_cast、const_cast和reinterpret_cast中的一种。其中,dynamic_cast支持运行时类型识别。
static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。当需要把一个较大的算术类型赋值给较小的类型时,static_cast 非常有用。此时,强制类型转换告诉程序的读者和编译器:我们知道并且不在乎潜在的精度损失。一般来说,如果编译器发现一个较大的算术类型试图赋值给较小的类型,就会给出警告信息;但是当我们执行了显式的类型转换后,警告信息就会被关闭了。
const_cast
const_cast只能改变运算对象的底层const:
const char *pc;
char *p = const_static<char *>(pc);
一旦我们去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。如果对象本身不是一个常量,使用强制类型转换获得写权限是合法的行为。然而如果对象是一个常量,再使用 const_cast 执行写操作就会产生未定义的后果。
const_cast常常用于有函数重载的上下文中。
reinterpret_cast
reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释。在指针之间转换,将一个类型的指针转换为另一个类型的指针,无关类型。interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。
dynamic_cast
dynamic_cast用于基类的指针或引用与派生类的指针或引用之间的转换,dynamic_cast运算符的使用形式如下所示:
dynamic_cast<type *>(e)
dynamic_cast<type &>(e)
dynamic_cast<type &&>(e)
其中,type必须是一个类类型,通常情况下该类型应该含有虚函数。在第一种形式中,e必须是一个有效指针;在第二种形式中,e必须是一个左值;在第三种形式中,e不能是左值。
在上面所有形式中,e的类型必须符合以下三个条件任意一个:e的类型是目标type的公有派生类、e的类型是目标type的公有基类、e类型就是目标type的类型。如果一条dynamic_cast语句的转换目标是指针类型并且失败了,则结果为0;如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个bad_cast异常。