一、何时需要强制类型转换
1. 例如:
double dval;
int ival;
ival *= dval;
计算机计算时会将ival从int型转换为double型,之后又转回int型,为了去掉“将ival从int型转换为double型”这个不必要的转换,可以使用强制类型转换:
ival *= static_cast<int>(dval);
2.可能存在多种转换时,可以通过强制类型转换指定一种特定的类型转换。
二、四种命名的强制类型转换
1.static_cast
(1)对于编译器隐式执行的任何类型转换,我们都可以换为由static_cast来显示完成:
double d = 97.0;
// cast specified to indicate that the conversion is intentional
char ch = static_cast<char>(d);
由较大类型转换为较小类型,如果是隐式的,编译器通常会产生警告,如果我们显示地提供强制类型转换,则可以关闭警告信息。
(2)对于编译器不提供的自动转换,我们可以使用static_cast来强制执行。例如:
void* p = &d; // ok: address of any data object can be stored in a void*
// ok: converts void* back to the original pointer type
double *dp = static_cast<double*>(p);
这里用static_cast将存放在void*中的指针值强制转换为原来的指针类型。
2.dynamic_cast
dynamic_cast支持运行时识别指针或引用所指向的对象。它可以将基类类型对象的引用或指针转换为同一继承层次中其他类型的引用或指针。
与其他强制类型转换不同,dynamic_cast涉及运行时类型检查。
3.const_cast
(1)用于去掉const特性。由于不能把一个const变量直接赋给一个非const变量,所以在需要这么做的时候,const_cast就可以派上用场。比较常用。
常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。
(2)添加const特性。比较少用。
4.reinterpret_cast
reinterpret_cast通常为操作数的位模式提供较低层次的重新解释。如
int *ip;
char *pc = reinterpret_cast<char*>(ip);
这么做之后,程序员必须永远记得pc所指向的真实对象其实是int型,而非字符数组,另外,编译器无法知道pc实际上是指向int型对象的指针。
建议:尽量避免使用强制类型转换。
特别是在使用reinterpret_cast时,我们发现此类强制转换总是非常危险的。相似的,使用const_cast也总是预示着设计缺陷。static_cast与dynamic_cast也不应频繁使用。