C++四种显式强制类型转换

前几日阅读《C++ Primer(第五版)》第141页的4.11.3节,学习了四种显式强制类型转换,现记录如下。

有时我们希望显式地将对象强制转换成另外一种类型。虽然有时不得不使用强制类型转换,但这种方法本质上是非常危险的。

一个命名的强制类型转换具有如下形式:

cast-name<type>(expression);

其中,type是转换的目标类型而expression是要转换的值。如果type是引用类型,则结果是左值。cast-name是static_cast、dynamic_cast、const_cast 和 reinterpret_cast 中的一种。

static_cast

任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。例如,通过将一个运算对象强制转换成double类型就能使表达式执行浮点数除法:

double slope = static_cast<double>(j) / i;

当需要把一个较大的算术类型赋值给较小的类型时,static_cast非常有用。此时,强制类型转换告诉程序的读者和编译器:我们知道并且不在乎潜在的精度损失。一般来说,如果编译器发现一个较大的算术类型试图赋值给较小的类型,就会给出警告信息;但是当我们执行了显式的类型转换后,警告信息就会被关闭了。

static_cast对于编译器无法自动执行的类型转换也非常有用。例如,我们可以用static_cast找回存在于void*指针中的值:

double d;
void* p = &amp;d;	//正确:任何非常量对象的地址都能存入void*
//正确:将void*转换回初始的指针类型
double *dp = static_cast<double*>(p);

void*是一种特殊的指针类型,可用于存放任意对象的地址。当我们把指针存放在void*中,并且使用static_cast将其强制转换回原来的类型时,应该确保指针的值保持不变。也就是说,强制转换的结果将与原始的地址值相等,因此我们必须确保转换后所得的类型就是指针所指的类型。类型一旦不符,将产生未定义的后果。

dynamic_cast

dynamic_cast支持运行时类型识别。待稍后补充。

const_cast

const_cast只能改变运算对象的底层const。const_cast中的类型必须是指针、引用或指向对象类型成员的指针。对于将常量对象转换成非常量对象的行为,我们一般称其为“去掉const性质(cast away the const)”。只有const_cast能改变表达式的常量属性。const_cast常常用于有函数重载的上下文中,但在其他情况下使用const_cast也就意味着程序存在某种设计缺陷。

reinterpret_cast

reinterpret_cast通常为运算对象的位模式提供较低层次上的重新解释。使用reinterpret_cast是非常危险的。

建议

强制类型转换干扰了正常的类型检查,因此我们强烈建议程序员避免使用强制类型转换。

旧式的强制类型转换

在早期版本的C++语言中,显式地进行强制类型转换包含两种形式:

type(expr);//函数形式的强制类型转换
(type)expr;//C语言风格的强制类型转换

与命名的强制类型转换相比,旧式的强制类型转换从表现形式上来说不那么清晰明了,容易被看漏,所以一旦转换过程出现问题,追踪起来也更加困难。

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.