C++的四种类型转换

22 篇文章 0 订阅

 在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    {    }    
void fun(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=new Test();    c->n=4;//编译出错   
 Test *d=const_cast<Test*>(c);    d->n=3;//OK
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值