1 C 语言中的强制类型转换
-
C 方式的强制类型转换
(Type)(Expression)
Type(Expression)
-
示例:粗暴的类型转换
-
Demo
#include <stdio.h> typedef void(PF)(int); //定义一个函数类型 struct Point { int x; int y; }; int main() { int v = 0x12345; PF* pf = (PF*)v; //这里将0x12345转化为一个函数地址,很可能出错 char c = char(v); Point* p = (Point*)v; pf(5); printf("p->x = %d ", p->x); printf("p->y = %d ", p->y); return 0; }
-
编译运行
段错误
-
-
C 方式强制类型转换存在的问题
- 过于粗暴:任意类型之间都可以进行转换,编译器很难判断其准确性
- 难以定位:在源码中无法快速定位所有使用强制类型转换的语句
2 新式类型转换
-
新式类型转换以 C++ 关键字的方式出现
- 编译器能够帮助检查潜在的问题
- 非常方便的在代码中定位
- 支持动态类型识别(
dynamic_cast
)
-
C++ 将强制类型转换分为 4 种不同的类型
static_cast
,const_cast
,dynamic_cast
,reinterpret_cast
- 用法:
xxx_cast<Type>(Expression)
-
static_cast
强制类型转换- 用于基本类型间的转换
- 不能用于基本类型指针间的转换
- 用于有继承关系类对象之间的转换和类指针之间的转换
-
const_cast
强制类型转换- 用于去除变量的只读属性
- 强制转换的目标类型必须是指针或引用
-
reinterpret_cast
强制类型转换- 用于指针类型间的强制转换
- 用于整数和指针类型间的强制转换
-
dynamic_cast
强制类型转换- 用于有继承关系的类指针间的转换
- 用于有交叉关系的类指针间的转换
- 具有类型检查的功能
- 需要虚函数的支持
-
示例:新式类型转换
-
Demo
#include <stdio.h> void static_cast_demo() { int i = 0x12345; char c = 'c'; int* pi = &i; char* pc = &c; c = static_cast<char>(i); //ok: int->char pc = static_cast<char*>(pi); //error: int*->char* } void const_cast_demo() { const int& j = 1; int& k = const_cast<int&>(j); //去除引用的常量属性 const int x = 2; int& y = const_cast<int&>(x); int z = const_cast<int>(x); //error: 只能是引用或指针 k = 5; printf("k = %d ", k); // 5 printf("j = %d ", j); // 5 y = 8; printf("x = %d ", x); // 2 printf("y = %d ", y); // 8 printf("&x = %p ", &x); // 0xbf93d3c0 printf("&y = %p ", &y); // 0xbf93d3c0 } void reinterpret_cast_demo() { int i = 0; char c = 'c'; int* pi = &i; char* pc = &c; pc = reinterpret_cast<char*>(pi); //ok: int*->char* pi = reinterpret_cast<int*>(pc); //ok: char*->int* pi = reinterpret_cast<int*>(i); //ok: int->int* c = reinterpret_cast<char>(i); //error: int->char } void dynamic_cast_demo() { int i = 0; int* pi = &i; char* pc = dynamic_cast<char*>(pi); //error } int main() { static_cast_demo(); const_cast_demo(); reinterpret_cast_demo(); dynamic_cast_demo(); return 0; }
-
编译
test.cpp: In function ‘void static_cast_demo()’: test.cpp:11: error: invalid static_cast from type ‘int*’ to type ‘char*’ test.cpp: In function ‘void const_cast_demo()’: test.cpp:22: error: invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type test.cpp: In function ‘void reinterpret_cast_demo()’: test.cpp:47: error: invalid cast from type ‘int’ to type ‘char’ test.cpp: In function ‘void dynamic_cast_demo()’: test.cpp:54: error: cannot dynamic_cast ‘pi’ (of type ‘int*’) to type ‘char*’ (target is not pointer or reference to class)
-