关键字 | 说明 |
---|---|
static_cast | 用于良性转换,一般不会导致意外发生,风险很低。 |
const_cast | 用于 const 与非 const、volatile 与非 volatile 之间的转换。 |
reinterpret_cast | 高度危险的转换,这种转换仅仅是对二进制位重新解释,是static_cast的互补 |
dynamic_cast | 借助 RTTI,用于类型安全的下行转换。上行转换与static_cast一样。 |
static_cast 没有类型检查来保证转换的安全性,不能用于无关类型之间的转换,例如:
static_cast 是在编译期间转换,转换失败的话会抛出一个编译错误。
int m = 100;long n = static_cast<long>(m); //宽转换,没有信息丢失 char ch = static_cast<char>(m); //窄转换,可能会丢失信息 int *p1 = static_cast<int*>(malloc(10 * sizeof(int))); //将void指针转换为具体类型指针 void *p2 = static_cast<void*>(p1); //将具体类型指针,转换为void指针 //下面的用法是错误的 float *p3 = static_cast<float*>(p1); //不能在两个具体类型的指针之间进行转换 p3 = static_cast<float*>(0X2DF9); //不能将整数转换为指针类型
const_cast 就是用来将 const/volatile 类型转换为非 const/volatile 类型。
const int n = 100; int *p = const_cast<int*>(&n); *p = 234; cout << " n = " << n << endl; //100 cout << " *p = " << *p << endl; //234
&n用来获取 n 的地址,它的类型为const int *,必须使用 const_cast 转换为int *类型后才能赋值给 p。由于 p 指向了 n,并且 n 占用的是栈内存,有写入权限,所以可以通过 p 修改 n 的值。
由于 C++ 对常量的处理更像是编译时期的#define,是一个值替换的过程,代码中所有使用 n 的地方在编译期间就被替换成了 100。换句话说,第 4 行代码被修改成了下面的形式:
cout << " n = " << 100 << endl; //100
reinterpret_cast 仅仅是对二进制位重新解释,不会借助已有的转换规则对数据进行调整。
reinterpret_cast 可以认为是 static_cast 的一种补充,一些 static_cast 不能完成的转换,就可以用 reinterpret_cast 来完成,例如两个具体类型指针之间的转换、int 和指针之间的转换。
//将 char* 转换为 float* char str[] = "http://c.biancheng.net"; float *p1 = reinterpret_cast<float*>(str); cout << *p1 << endl; //3.0262e+29 //将 int 转换为 int* int *p = reinterpret_cast<int*>(100); cout << *p << endl; //100
dynamic_cast 用于在类的继承层次之间进行类型转换,它既允许上行转换,也允许下行转换。
dynamic_cast 与 static_cast 是相对的。dynamic_cast 会在程序运行期间借助 RTTI 进行类型转换,这就要求基类必须包含虚函数;static_cast 在编译期间完成类型转换,能够更加及时地发现错误。
//下行转换 class A { public: virtual void func() const { cout<<"Class A"<<endl; } private: int m_a; }; class B : public A { public: virtual void func() const { cout<<"Class B"<<endl; } private: int m_b; }; class C : public B { public: virtual void func() const { cout<<"Class C"<<endl; } private: int m_c; }; class D : public C { public: virtual void func() const { cout<<"Class D"<<endl; } private: int m_d; }; int main(){ A *pa = new A(); B *pb; C *pc; //情况① pb = dynamic_cast<B*>(pa); //向下转型失败 pc = dynamic_cast<C*>(pa); //向下转型失败 //情况② pa = new D(); //向上转型都是允许的 pb = dynamic_cast<B*>(pa); //向下转型成功 pc = dynamic_cast<C*>(pa); //向下转型成功 return 0; }