首页 > 代码库 > C++的显示转换

C++的显示转换

利用显示转换使得我们可以很容易发现它们,因为通过名字就能找到:

 static_cast用于“良性”和“适度良性”转换,包括不用强制转换
 const_cast 对“const”和“volatile”进行转换
 reinterpret_cast转换为完全不同的意思,为了安全使用它,关键必须转换为原来的类型 。这是所有转换中最危险的
 dynamic_cast用于类型安全向下转换 

1.静态转换(static_cast)

static_cast包含的转换类型包括典型的非强制变换,窄化(有信息丢失)变换,使用void*的强制转换,隐式类型变换和类层次的静态定位。

用法:static_cast < type-id > ( expression )    

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类和子类之间指针或引用的转换。
  进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
  进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的指针。

void func(int){}

int main()

{

   int i=0x7fff;

   long l;

   float f;

 

   //典型的非强制类型转换

   l=i;

   f=i;

 

   l=static_cast<long>(i);

   f=static_cast<float>(i);

 

   //窄化变换

   i=l;

   i=f;

  

   i=static_cast<int>(l);

   i=static_cast<int>(f);

   char c=static_cast<char>(i);

 

   //使用void* 的强制变换

   void* vp=&i;

   float* fp=(float*)vp;

 

   //Error:C++中不用强制转换是不能从void* 中赋值的

  // fp=vp;

 

   fp=static_cast<float*>(vp);

 

   //隐式类型变换

   double d=0.0;

   int x=d;

 

   x=static_cast<int>(d);

   func(d);

   func(static_cast<int>(d));

   return 0;

}

 

2.常量变换(const_cast)

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

 

如果从const转换为非const,或从volatile转换为非volatile,或者从非const转换为const ,非volatile转换为volatile可以使用const_cast。

 

int main()

{

       const int i=0;

       //Error:取得const对象的指针,不用转换是不能把它赋值给非const指针的

      // int* j=&i;

 

        int* j=(int*)&i;

        j=const_cast<int*>(&i);

     

 //Error:const_cast<type_id>(expression)中除了const 或volatile修饰之外,type_id和expression的类型是一样的

       // long* l=const_cast<long*>(&i);

 

        volatile int k=0;

        int* u=const_cast<int*> (&k);

      

}

 

3.重解释转换(reinterpret_cast)

用法:reinterpret_cast<type-id> (expression)
type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
它可以把一个指针转换成一个整数也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。

这是最不安全的一种转换机制。reinterpret_cast把对象假象成另一个完全一个不同类型的对象。reinterpret_cast的思想就是当需要使用的时候,所得到的东西已经不同了,以至于它不能用于类型的原来目的,除非再次把它转换回来。

#include <iostream>

using namespace std;

const int sz=100;

 

struct X{int a[sz];};

 

void print(X* x)

{

       for(int i=0;i<sz;i++)

       {

              cout<<x->a[i]<<" ";

             

       }

       cout<<endl<<"-----------------"<<endl;

}

int main()

{

       X x;

       print(&x);                  //出来的是没有意义的值

 

       int* xp=reinterpret_cast<int*>(&x);

       for(int* i=xp;i<xp+sz;i++)

       {

              *i=0;

       }

       print(reinterpret_cast<X*>(xp));

       print(&x);

}