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 转换到 双精度整数9 , static_cast 需要正确地为双精度整数 d 补足比特位。其结果为 9.0 。而 reinterpret_cast 的行为却不同 :
int n=9;
double d=reinterdivt_cast (n);
这次 , 结果有所不同 . 在进行计算以后 , d 包含无用值 . 这是因为 reinterdivt_cast 仅仅是复制 n 的比特位到 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 }

浙公网安备 33010602011771号