C++的四种类型转换

来源:互联网 发布:tv霸网络电视安卓版 编辑:程序博客网 时间:2024/06/05 21:01

 在C中进行强制类型转换,直接()就可以了。在c++中,提供了四种类型转换,static_cast、dynamic_cast、reinterp_cast、const_cast。当然,如果你要用()强转也行,c++是兼容c的。关于这四种转换,网上有介绍很仔细很详细的。我这里只想简单的介绍其常用的规则。这些东西大多都用在转换指针上。
static_cast

快速的类型转换,如果可以转换则一定会成功。代价是被转换的类型可能不是正确的类型,后面调用就会有可能出错。什么叫“可以转换”?就是有一条确定的转换路径。如果不可以,会编译出错的。
用法:static_cast < type-id > ( expression )
常常用于下面几种情况:

用于类层次结构中基类和子类之间指针或引用的转换。进行上行转换(把子类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。 void指针转换成目标类型的指针(不安全!!) 把任何类型的表达式转换成void类型。 dynamic_cast检查类型的安全的转换,   无法完成的转换会返回NULL(转换指针)或者抛出异常(转换引用).   效率较低。比如把父类对象指针转换成子类指针就会返回NULL。有这样的特性,有时候我们可以利用它来判断某个指针指向的对象是哪个对象。
reinterp_cast简单的转换,万能的转换。也是危险的,程序员得自己保证它的安全。
const_cast用来修改类型的const或volatile属性。
例如:
C++代码
class  A         {         };                
class     B   :   public  A         {         };                        
class   C        {          };                
class   D  :   public   A        {          };                
class   E   :   public   D,   public  B         {             ...         };  
A*   pa   =  new   B();   //   pa   实际指向一个B对象        
B*   pb   =  dynamic_cast<B*>(pa);   //   转换成   B对象指针,   这里会成功,因为  pa实际指向一个B对象        
pb   =   static_cast<B*>(pa);     //  成功,因为A和B之间有明确的继承关系        
delete   pa;                        
pa  =   new   A();       //   现在pa   指向一个A对象        
pb   =  dynamic_cast<B*>(pa);       //   不成功,返回0,   因为pa不是指向一个B对象        
pb   =   static_cast<B*>(pa);     //   成功,  同上,但是这个pb指针在这里使用可能会出问题(并不是一定会出)                        
C*   pc   =  static_cast<C*>(pa);   //   这里编译就会出错.因为C*和A*之间没什么连系,  编译器不知道怎么转换         C*   pc   =   reinterp_cast<C*>(pa);   //  成功,   类型是转过来了,指针还是指向一个A对象(危险!!)                
//  下面看看向上转型,这里有多继承.        
E*   pe   =   new   E();         A*   pa2  =   dynamic_cast<A*>(pd);   //   编译错误!   因为E包含A从两条不同的路径        
A*   pa3   =   static_cast<A*>(pd);     //   同上        
A*  pa4   =   static_cast<A*>(static_cast<B*>(pd));     //  可以,通常这里会对指针值做调整.因为第二个基类的起点在派生类里可能会有变化        
A*   pa5   =  reinterp_cast<A*>(pd);   //   可以,  但这里不会调整指针值(危险!!)              
class Base    {    }    
class Derive1:public Base    {    }    
class Derive2 :public Base    {    }    
voidfun(Base *p)//如果这里p只有两种可能Derive1和Dervie2    
{      Derive1*p1=dynamic_cast<Dervie1*>(p);     
 if(p!=NULL)      {//p指向的是Dervie1的对象      }      
else     {//p指向的是Dervie2的对象      }    }      
class Test    {    public:     int n;    }    
const Test *c=newTest();    c->n=4;//编译出错   
 Test*d=const_cast<Test*>(c);    d->n=3;//OK
原创粉丝点击