静态转换(static_cast)
static_cast全部用于明确定义的变换,包括编译器允许我们所做的不用强制转换的“安全”变换和不太安全
但是清楚定义的变换,static_cast包含的转换类型包括典型的非强制变换,窄化(有信息丢失)变换,使
用void*的强制变换,隐式类型变换和类层次的静态定位。
例如:
#include<iostream> using namespace std; int fun(int x){} int main() { int i=0x7fff; long l;float f; //将int提升到long,float是不会有问题的 l=i;f=i; l=static_cast<long>(i); f=static_cast<float>(i); //窄化变换,可能会造成信息的丢失 i=l;i=f; char c=static_cast<char>(i); void* p=&i; float* fp=(float*)p; fp=static_cast<float*>(p); double d=0.0; int x=d; x=static_cast<int>(d); fun(d); fun(static_cast<int>(d)); return 0; }
常量转换(const_cast)
如果从const转换为非const或从volatile转换为非volatile,可以使用const_cast。这是const_cast唯一
允许的转换,如果进行别的转换就可能要使用单独的表达式或者可能会得到一个编译错误。
如果取得了const对象的地址,就可以生成一个指向const的指针,不用转换时不能将它赋给非
const指针的。
#include<iostream> using namespace std; int main() { const int i=0; int* j=(int*)&i; j=const_cast<int*>(&i); volatile int k=0; int* u=const_cast<int*>(&k); return 0; }
重解释转换(reinterpret_cast)
这是最不安全的一种转换机制,最有可能出现问题。reinterpret_cast把对象假象为模式,当他是一个
完全不同类型的对象。这是低级的位操作。在使用reinterpret_cast做任何事之前,实际上总是需要
reinterpret_cast回到原来的类型(或者把变量看作是他原来的类型)
#include<iostream> using namespace std; const int sz=100; struct X{int a[sz];}; void print(X* x) { for(int i=0;i<sz;i++) cout<<x->a[i]<<' '; cout<<endl<<"---------------"<<endl; } int main() { X x; print(&x); int* xp=reinterpret_cast<int*>(&x); for(int* i=xp;i<xp+sz;i++) *i=0; print(reinterpret_cast<X*>(xp)); print(&x); return 0; }
在这个例子中struct X只包含一个整型数组,但是当用X x在堆栈中创建一个变量时,该结构体中的每一个整型变量的值
都没有意义(通过使用函数print()把结构体中的每一个整型值显示出来可以表明这一点)。为了初始化他们,取得
x的地址并转换为一个整型指针,该指针然后遍历这个数组,置数组中每个值为0.
reinterpret_cast的思想就是当需要使用的时候,所得到的东西已经不同了,以至于它不能用于类型的原来目的,除非再次
把它转换过来,使用reinterpret_cast通常是一种不明智,不方便的编程方式,但是当必须使用它是还是非常有用的