c++中的类型转换

类型转换:

1.static_cast<目标类型>(表达式)
该运算符没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①父类和子类之间指针或引用的转换。
  进行上行转换(把子类的指针或引用转换成基类表示)是安全的;可以抛弃是安全的。
  进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。增加是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。

注意:static_cast 不能转换掉expression的const、volitale、或者__unaligned属性。

对于

char *p;

int i=static_cast<int>(p);是错误的,不存在char*类型到int类型的转换

2.dynamic_cast< type-id > ( expression )
该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;
如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast 的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast 更安全。

#include <iostream>                                                                                      
using namespace std;                                                                                     
                                                                                                         
class B{                                                                                                 
   public:                                                                                               
   int b;                                                                                                
   virtual void foo(){};                                                                                 
};                                                                                                          
class D:public B{                                                                                        
   public:                                                                                               
   char *d[100];                                                                                         
};                                                                                                       
class E:public B{                                                                                        
    public :                                                                                                
        int e;                                                                                                 
};                                                                                                       
int main(){                                                                                                 
    //下行转换 ,dyn}amic_cast具有类型检查功能,更安全                                                      
   B *pb=new B;                                                                                               D *pd1 =    static_cast<D*> (pb);   //pd1会指向D对象,但是如果访问D中的d,就可能不安全。                 
   D *pd2 = dynamic_cast<D*>(pb);  //而,此处pd2 将会是空指针,且要求B中有虚函数,而static则没这个要求   
   //上行转换 ,两个方法没什么区别                                   
   D *son=new D;                                                    
   B *b1=static_cast<B*>(son);                                      
   B *b2=dynamic_cast<B*>(son);                                     
   //另外,注意,如果是同类型直接使用这两个转换,没有任何问题       
   //另外,dynamic_cast还支持交叉转换(cross cast)。如下代码所示   
    E *e=dynamic_cast<E*>(son);    //static_cast不能使用这个  
   cout<<e<<endl;// 此时是空指针0                            
}                                                            

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

该运算符的用法比较多。

reinterpret_cast 是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。 ( 这句话是 C++ 编程思想中的原话 )

static_cast  reinterpret_cast 操作符修改了操作数类型。它们不是互逆的; static_cast 在编译时使用类型信息执行转换,在转换执行必要的检测 ( 诸如指针越界计算 类型检查 ). 其操作数相对是安全的。另一方面; reinterpret_cast仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换, 例子如下: 
int n=9; double d=static_cast < double > (n); 

上面的例子中 我们将一个变量从 int 转换到 double 。 这些类型的二进制表达式是不同的。 要将整数 转换到 双精度整数9 , static_cast 需要正确地为双精度整数 补足比特位。其结果为 9.0 。而 reinterpret_cast 的行为却不同 

int n=9;

double d=reinterdivt_cast (n);

这次 结果有所不同 在进行计算以后 , d 包含无用值 这是因为 reinterdivt_cast 仅仅是复制 的比特位到 d, 没有进行必要的分析。 

const_cast<>()

const A a;

a.data=10;(wrong)

const_cast<A&> (a).data=10

4、const_cast<目标类型> (expression)

该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。const_cast只能用于指针或引用。

一、常量指针被转化成非常量的指针,并且仍然指向原来的对象;

二、常量引用被转换成非常量的引用,并且仍然指向原来的对象;

 1 #include<stdio.h>
 2 #include<iostream>
 3 using namespace std;
 4 int main()
 5 {
 6     int a =4;
 7     int *p1 = &a;
 8     const int *p2 = p1;
 9     printf("%d\n",&p1);
10     printf("%d\n",&p2); /// not same, but P1, P2 's value is same.
11     int *p3 = const_cast<int *>(p2);
12     *p3 = 6;
13     *p2 = 5; // p2 is still const
14     printf("%d\n",*p3);
15     printf("%d\n",*p2);//eror
16 }

 

 

posted @ 2014-06-15 13:38  不要等待  阅读(181)  评论(0)    收藏  举报