从c转向c++时,类型转换出现了一些疑惑,查阅了一些资料和博文,整理如下。
1. 隐式类型转换
这类转换主要发生在类型不同的赋值和计算过程中,C/C++中均存在
int ival = 3;
double dval = 3.124;
ival + dval //ival被提升为double类型
int *p = 0; // 0被转换为了int* 类型
ival = dval; // dval被转换为了int类型
还有很多类似的例子,比如传入函数的实参时,实参和形参类型不一致,实参转换为形参类型;函数返回值和return表达式类型不一致,转换为返回值等等
2. 显示类型转换
也被称为强制转换,顾名思义就是表达式中表明了如何转换。
-
C风格:(type-id)
- C风格类型转换的底层实现一般禁止使用不安全的转换,也就是说其底层实现不是固定的使用哪种转换方式
-
C++风格:static_cast, dynamic_cast, reinterpret_cast, const_cast
- 这里需要说明的是,为了清楚从字面上看出转换方式和潜在的风险,我们在编写代码的时候,尽量使用C++风格的强制转换,摒弃(type-id)的转换写法
下面对C++中几个转换类型做一些说明
-
static_cast
用法
static_cast<type-id>(expression)
将expression强制转换为type-id类型,该运算符的特点是转换时不进行检查,所以不具备安全性(特别是将父类指针向下转换为子类指针时,不对指针所指向的对象做动态类型检查)
不能转换掉expression的const、volatile、或者__unaligned属性。他也不是用来去掉static属性的
可以用于指针、引用、基本类型、void类型等转换,对type-id和expression类型一致性没有要求
-
dynamic_cast
用法同上, type-id类的指针、引用或者void*类型;expression必须和type-id在类型上(此处指的是大范围的类型,指针、引用等,不具体到某个类)保持一致;
具备类型检查的功能(所以有上述类型一致要求),在类指针的下行转换上,安全性要好
-
const_cast
此运算符是用来消除类型的const和volatile属性的。
-
举例说明
const char m = 't';
const char *cm = &m;
char *n = cm // error
char *n = const_cast<char*>(cm) //OK
*n = 'a'; // OK
cout << *n << endl; // 'a'-
char *n = (char *)cm
也是编译通过的,因为指针之间转换不做类型检查
-
使用const_cast机会非常少,如果写代码需要用到const_cast,很大程度上说明代码设计有问题!
-
reinterpret_cast
- 用于进行没有任何关联之间的转换,比如一个字符指针转换为一个整形数。
总结来说:
- 最常用的还是static_cast和dynamic_static,其中前者更常用,后者多用于基类指针向下转换为子类指针。