C++中四大强制类型转换!

C++中有四中强制类型转换:static_cast,const_cast,reinterpret_cast,dynamic_cast,下面来逐一解释。


1)static_cast<T* >(a)

将地址a转换成类型T,T和a必须是指针、引用、基本数据类型或枚举类型。在运行时转换过程中,不进行类型检查来确保转换的安全性。

class B { ... };

class D : public B { ... };

void f(B* pb, D* pd)

{

   D* pd2 = static_cast<D*>(pb);        // 不安全, pb可能只是B的指针
   B* pb2 = static_cast<B*>(pd);        // 安全的
   ...

}

在C++语言中static_cast用于数据类型的强制转换,强制将一种数据类型转换为另一种数据类型。例如将整型数据转换为浮点型数据,它主要有如下几种用法:
    (1)用于类层次结构中基类和派生类之间指针或引用的转换,进行上行转换(把派生类的指针或引用转换成基类表示)是安全的,进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的。
    (2)用于基本数据类型之间的转换,如把int转换成char。这种转换的安全也要开发人员来保证
    (3)把空指针转换成目标类型的空指针
    (4)把任何类型的表达式转换为void类型
    注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。


2)dynamic_cast<T* >(a)

完成类层次结构中的提升,T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。表达式dynamic_cast<T*>(a) 将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型,该操作将返回一个空指针。

class A { ... };

class B { ... };

void f()
{

  A* pa = new A;

  B* pb = new B;

  void* pv = dynamic_cast<A*>(pa);

  // pv 现在指向了一个类型为A的对象

  ...

  pv = dynamic_cast<B*>(pb);

  // pv 现在指向了一个类型为B的对象
}

用法:dynamic_cast<type_id> (expression)

   (1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

   (2)不能用于内置的基本数据类型的强制转换。

   (3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

   (4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

        需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意只有定义了虚函数的类才有虚函数表。


3)const_cast<T* >(a)

去掉类型中的常量,除了const或不稳定的变址数,T和a必须是同类型。表达式const_cast<T*>(a)被用于从一个类中去除以下属性:const、volatile和_unaligned。

class A { ... };

void f()
{

const A *pa = new A;//const对象

A *pb;//非const对象
//pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
pb = const_cast<A*>(pa); // 现在OK了
...
}

const_cast是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。

用法:const_cast<type_id> (expression)
   (1) 该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
   (2)常量指针被转化成非常量指针,并且仍然指向原来的对象;
   (3)常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。


4) reinterpret_cast<T* >(a)

任何指针都可以转换成其它类型的指针,T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。表达式reinterpret_cast<T*>(a)能够用于将char*到int*,或者One_class*到Unrelated_class*等类似这样的转换,因此是不安全的。

class A { ... };

class B { ... };

void f()
{
  A* pa = new A;

  void* pv = reinterpret_cast<A*>(pa);
  // pv 现在指向了一个类型为A的对象,这可能是不安全的
  ...
}

在C++语言中,reinterpret_cast主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型

用法:reinterpret_cast<type_id> (expression)
   (1)    type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
   (2) 它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
    注意:在使用reinterpret_cast强制转换过程仅仅只是比特位的拷贝,因此在使用过程中需要特别谨慎!

 


参考:http://www.cnblogs.com/tgycoder/p/5303701.html

posted @ 2019-03-19 22:51  鲁太师  阅读(295)  评论(0编辑  收藏  举报