您的位置:首页 > 编程语言 > C语言/C++

c++强制转型

2017-06-25 20:32 141 查看
##const_cast<T*>(a)

  它用于从一个类中去除以下这些属性:const、volatile和__unaligned。

 calss A{ // ...}

  void Function()

  {

   const A *pConstObj = new A;

   A *pObj = pConstObj;//ERROR:不能将const对象指针赋值给非const对象

   pObj = const_cast<A*>{ pConstObj};//ok

  }

  这种强制转型的目的简单明确,使用情形比较单一,易于掌握。

##dynamic_cast<T*>(a)

 它将a值转换成类型为T的对象指针,主要用来实现类层次结构的提升,在很多书中它被称作“安全的向下转型(Safe Downcasting)”,用于继承体系中的向下转型,将基类指针转换为派生类指针,这种转换较为严格和安全。如下面的代码片段所示:

 class B{...};

 class D : public B{//...};

 void Function(D *pObjD)

 {x

   D *pObj = dynamic_cast<D*>(pobjD);

   //...

 }

  如果pObjD指向一个D类型的对象,pObj则指向该对象,所以对该指针指向D类型的任何操作都是安全的。但是,如果pObjD指向

的是一个B类型的对象,pObj将是一个空指针,这在一定程度上保证了程序员所需要的“安全”,只是,它也付出了一定的运行时代价,而且代价非常大,实现相当慢。有一种通用实现是通过对类名称进行字符串比较来实现的,只是其在继承体系中所处的位置越深,对strcmp的调用越多,带价也就越大。如果应用对性能要求较高,那么请放弃dynamic_cast。

##reinterpret_cast<T*>(a)

 它能够用于诸如One_class* 到 Unrelated_class*这样的不相关类型之间的转换,因此它是不安全的。其与C风格的强制转型很是相似。

 class A { // ...};

 class B { // ...};

 void f()

 {

   A* pa = new A;

   B* pb = reinterpret_cast<B*>(pa);

   //...

 }

  在不了解A、B内存布局的情况下,强行将其进行转换,很有可能出现内存膨胀或截断。

##static_cast<T*>(a)

 
它将a的值转换为模版中指定的类型T。但是,在运行时转换过程中,他不会进行类型检查,不能确保转换的安全性。如以下代码片段所示:

  class B{...}

  class D : public B{...}

 void Function(B* pb,D* pd)

 {

   D* pd2 = static_cast<D*>(pb);//不安全

   B* pb2 = static_cast<B*>(pd);//安全的

 }

  之所以说第一种是不安全的,是因为如果pb指向的仅仅是一个基类B的对象,那么就会凭空生成继承信息。至于这些信息是什么、正确与否,无从得知。所以对它进行D类型的操作将是不安全的。

  C++是一种强类型的编程语言,其规则设计为“保证不会发生类型错误”。在理论层面上,如果希望程序顺利地通过编译,就不应该试图对任何对象做任何不安全的操作。不幸的是,继承自C语言的强制转型破坏了类型系统,所以建议尽量少的使用强制转型,无论是旧的C风格的还是新的C++风格。如果发现自己是用了强制转型,那么一定要小心,这可能就是程序出现的一个信号。

##请记住: 由于强制转型无所不能,会给C++程序带来很大的安全隐患,因此建议在C++代码中,努力将强制转型减到最少。

 

                                          转自《编写高质量代码——改善C++程序的150个建议》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 强制转型