利用显示转换使得我们可以很容易发现它们,因为通过名字就能找到:
static_cast | 用于“良性”和“适度良性”转换,包括不用强制转换 |
const_cast | 对“const”和“volatile”进行转换 |
reinterpret_cast | 转换为完全不同的意思,为了安全使用它,关键必须转换为原来的类型 。这是所有转换中最危险的 |
dynamic_cast | 用于类型安全向下转换 |
1.静态转换(static_cast)
static_cast包含的转换类型包括典型的非强制变换,窄化(有信息丢失)变换,使用void*的强制转换,隐式类型变换和类层次的静态定位。
用法:static_cast < type-id > ( expression )
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类和子类之间指针或引用的转换。
进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的指针。
void func(int){}
int main()
{
int i=0x7fff;
long l;
float f;
//典型的非强制类型转换
l=i;
f=i;
l=static_cast<long>(i);
f=static_cast<float>(i);
//窄化变换
i=l;
i=f;
i=static_cast<int>(l);
i=static_cast<int>(f);
char c=static_cast<char>(i);
//使用void* 的强制变换
void* vp=&i;
float* fp=(float*)vp;
//Error:C++中不用强制转换是不能从void* 中赋值的
// fp=vp;
fp=static_cast<float*>(vp);
//隐式类型变换
double d=0.0;
int x=d;
x=static_cast<int>(d);
func(d);
func(static_cast<int>(d));
return 0;
}
2.常量变换(const_cast)
用法:const_cast<type_id> (expression)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;
如果从const转换为非const,或从volatile转换为非volatile,或者从非const转换为const ,非volatile转换为volatile可以使用const_cast。
int main()
{
const int i=0;
//Error:取得const对象的指针,不用转换是不能把它赋值给非const指针的
// int* j=&i;
int* j=(int*)&i;
j=const_cast<int*>(&i);
//Error:const_cast<type_id>(expression)中除了const 或volatile修饰之外,type_id和expression的类型是一样的
// long* l=const_cast<long*>(&i);
volatile int k=0;
int* u=const_cast<int*> (&k);
}
3.重解释转换(reinterpret_cast)
用法:reinterpret_cast<type-id> (expression)
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
这是最不安全的一种转换机制。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);
}
C++的显示转换