在编程中,类型转换在所难免,在此我将介绍一下C++中常用的隐式转换和强制类型转换。
关于隐式转换:
在C++中,某些类型之间存在相关的依赖关系,若两种类型相关,则可以再需要某种类型的操作数位置上,使用该类型的相关类型对象或值。
C++并不是吧两个不同类型的值直接加在一起,而提供了一组转换规则,一边在执行算数操作之前,将两个操作数转换为同一种数据类型。这些转换规则由编译器自动执行,无需我们再介入。因此,也被成为隐式转换。
发生隐式转换的情况:
1.在混合类型的表达式中,其操作数被转换为相同类型。
2.用作条件的表达式(?:,!,&&,||,if,while,for,do while)被转换为bool类型。
3.用一表达式初始化某个变量,或将一表达式被转换为该变量的类型。
隐式转换类型:
1.指针转换:在使用数组时,大多数情况下数组都会自动转换为指向第一个元素的指针。
int ia[10];
int *ip = ia;
C++还提供了另外两种指针转换:指向任意数据类型的指针都可以转换为void*类型,整型数值常量0可转换为任意指针类型。
2.转换为bool类型:算数值和指针值都可以转换为bool类型。如果指针或算数值为0,则其bool值为false,而其他值则为true。
if (cp)
while (*cp)
3.算术类型与bool类型的转换:可将bool对象转换为int型。true变为1,false则为0。
4.转换与枚举类型:C++自动将枚举类型的对象或枚举成员转换为整型,其转换结果可用于任何要求使用整数的地方。
5.转换为const对象:当使用非const初始化const对象的引用时,系统将非const对象转换为const对象。此外还可以将非const对象的地址转换为指向相关const类型的指针。
int i;
const int ci = 0;
const int &j = i;
const int *p = &ci;
6.由标准库类型定义的转换:类类型可以定义由编译器自动执行的类型转换。
string s;
while (cin >> s)
其中使用了IO标准库定义的类型转换。
关于显示转换:
显示转换也成为强制类型转换,虽然有时候确实需要强制类型转换,但本质非常危险,应该尽量避免使用强制类型转换。
尽管不建议使用强制类型转换,但还是有一些情况需要使用:
因为要覆盖通常的标准转换,所以需要显示使用强制类型转换。例如:
double dval;
int ival;
ival *= dval;
这时,需要将ival转换为double型,然后将乘法操作的double型结截尾为int型,再赋值给ival。这样回事的其中多了ival转换为double型这个不必要的转换,则需要强制类型转换。
还有一个原因就是:可能存在多种转换时,需要选择一种特定的类型转换。
现在来讨论下命名的强制类型转换,具体格式如下:
cast-name<type> (expression);
cast-name为命名的强制类型转换符号,type为转换的目标类型,expression为被强制转换的值。
1.dynamic_cast
支持运行识别指针或引用所指向的对象。对dynamic_cast的详细讨论将在下一篇(RTTI)详细解释。
2.const_cast
顾名思义,就是将表达式的const属性转换掉。比如:
const char *pc_str;
char *pc = string_copy(const_cast<char *>(pc_str));
只用使用const_cast才能将const性质转换掉。在这种情况下,试图使用其他三种形式的强制转换都会导致编译时的错误。类似地,除了添加或者删除const特性,用const_cast符来执行其他任何类型转换,都会引起编译错误。
3.static_cast
编译器隐式执行的任何类型转换都可以由static_cast显式完成。当要讲一个较大的算数类型复制给较小的类型时,使用强制类型转换非常重要。此时,相当于告诉编译器我们忽略精度的损失,警告信息当然也会被关闭。
当编译器不提供自动转换时,也可以用static_cast来转换。
4.repinterpret_cast
通常作为操作数的位模式提供较低层次的重新解释。(repinterpret_cast本质上依赖于机器,但为了安全的使用它,我们必须理解所涉及的数据类型,以及编译器实现强制类型转换的细节。)例如:
int *ip;
char *pc = reinterpret_cast<cahr *>(ip);
此时通过转换后,pc实际上指向的对象是int型而非字符数组。
(注:我们在平时编程中还是最好避免使用强制类型转换,一面出现无法预测的错误。)
说到C++中的强制类型转换,还记得C中的强制类型转换:
type(expr);
(type)expr;
这两种强制类型转换在C++中仍然支持。支持C语言中的强制类型转换符号也是为了让C++保持与C语言的兼容性。