C++为了严格限制类型转换,规范类型转换,提供了4种类型转换运算符:dynamic_cast、const_cast、static_cast、reinterpret_cast。
- dynamic_cast
dynamic_cast用于将派生类向上转换为其(直接或间接)可访问基类。例如:
若向上转换成功,dynamic_cast返回目标类型的对像;若向上转换/向下转换不成功,则返回NULL指针。实际上,dynamic_cast反映了is-a关系模型中派生类均为基类对象的特点,因此这样的转换是安全的。/* dynamic_cast<目标类型>(待转换类型对象) */ //类base是类inheritance的基类,objbase、objinheri分别是这两个类的对象 base *pb; inheritance *pinheri=&objinheri; pb=dynamic_cast<base *>(pinheri);//返回指向inheritance对象的base指针
相对static_cast来说,dynamic_cast能够在运行时检查向下转换不可行,并返回一个NULL,因此其转换更加安全。
- const_cast
const_cast则用于改变同类对象的const或者volatile属性,多用于在需要修改const常量时临时修改,但使用时需要防止不能被修改的值被修改。
使用代码如下:/* const_cast<目标类型>(待转换类型对象) */ //类base是类inheritance的基类,objbase、objinheri分别是这两个类的对象 inheritance *pcinheri; const inheritance *pcinheri; pcinheri=const_cast<inheritance *>(pinheri);
- static_cast
static_cast可以实现几种转换:
#从派生类到基类的向上转换
#从基类到派生类的向下转换(但不安全,因为只是在编译时不报错,但实际运行可能出问题,因为基类没有派生类的新增成员。如果在写代码时不用static_cast,这样是非法的)
#基本类型间的转换,如int到char,但高位会被截断/舍弃。
#任意类型与空指针(指void指针)的转换
使用代码如下:
使用static_cast可以改变指针的指向,但这里*pb的大小似乎取决于pb类型(即base指针),而不是pb的指向。/* static_cast<目标类型>(待转换类型对象) */ //类base是类inheritance的基类,objbase、objinheri分别是这两个类的对象 //dynamic_cast base objbase=base(1); base *pb; cout<<"The value of objbase is:"; objbase.show(); cout<<endl; inheritance objinheri=inheritance(2,3); cout<<"The value of objinheri is:"; objinheri.show(); cout<<endl; inheritance *pinheri=&objinheri; cout<<"size and position of base object:"<<sizeof(objbase)<<","<<&objbase<<endl; cout<<"size and position of inheritance object:"<<sizeof(objinheri) <<","<<&objinheri<<endl; cout<<"Now pb pointed to objinheri."<<endl; pb=static_cast<base *>(&objinheri); cout<<"Now the value that pb pointed to is :"; pb->show(); cout<<endl; cout<<"size and position of object that pb pointed to:"<<sizeof(*pb)<<","<<pb<<endl; //pinheri=&objbase; //正常而言不允许这么干,而static_cast则允许在编译时这么干 cout<<"Now pinheri pointed to objbase."<<endl; pinheri=static_cast<inheritance *>(&objbase); cout<<"Now the value that pinheri pointed to is :"; pinheri->show(); cout<<endl; cout<<"size and position of object that pinheri pointed to:"<<sizeof(*pinheri) <<","<<pinheri<<endl; cin.get(); -----输出结果 The value of objbase is:1 The value of objinheri is:23 size and position of base object:8,0039F72C size and position of inheritance object:12,0039F70C Now pb pointed to objinheri. Now the value that pb pointed to is :23 size and position of object that pb pointed to:8,0039F70C Now pinheri pointed to objbase. Now the value that pinheri pointed to is :1 size and position of object that pinheri pointed to:12,0039F72C
- reinterpret_cast
reinterpret_cast用在任意类型之间的转换,但这只是在编译阶段是安全的,在实际运行时可能会出现难以意料的后果以至于程序崩溃。
允许的转换类型有:
#任意指针(或引用)类型之间的转换;
#指针与足够大的整数类型之间的转换;
#从整数类型(包括枚举类型)到指针类型,无视大小。
使用reinterpret_cast可能会发生位截断使得部分信息丢失。