C++的四种类型转化符

C++有四种强制类型转换符,分别是dynamic_cast,const_cast,static_cast,reinterpret_cast。
其中dynamic_cast与运行时类型转换密切相关,在这里我们先介绍dynamic_cast,其他三种在后面介绍。
static_cast在编译时期强制转换,dynamic_cast在运行时期转换(较安全)

static_cast是c语言的强制转换代替品,dynamic_cast可以帮助你实现虚函数的功能

1、dynamic_cast运算符
该转换符用于 将一个指向派生类的基类指针或引用转换为派生类的指针或引用
注意:dynamic_cast转换符只能用于含有虚函数的类,其表达式为  dynamic_cast<类型>(表达式)
其中的类型是指把表达式要转换成的目标类型,比如含有虚函数的基类B和从基类B派生出的派生类D,则:
B *pb; 
D *pd, md;  
pb = &md; 
pd = dynamic_cast<D *>(pb); 
最后一条语句表示把指向派生类D的基类指针pb转换为派生类D的指针,然后将这个指针赋给派生类D的指针pd,有人可能会觉得这样做没有意义,既然指针pd要指向派生类为什么不 pd = &md;这样做更直接呢?有些时候我们需要强制转换,比如如果指向派生类的基类指针B想访问派生类D中的除虚函数之外的成员时就需要把该指针转换为指向派生类D的指针,以达到访问派生类D中特有的成员的目的,比如派生类D中含有特有的成员函数g(),这时可以这样来访问该成员 dynamic_cast<D *>(pb)->g();因为dynamic_cast转换后的结果是一个指向派生类的指针,所以可以这样访问派生类中特有的成员。但是该语句不影响原来的指针的类型,即基类指针pb仍然是指向基类B的。如果单独使用该指针仍然不能访问派生类中特有的成员。一般情况下不推见这样使用dynamic_cast转换符,因为dynamic_cast的转换并不会总是成功的,具体情况在后面介绍。

dynamic_cast的注意事项
dynamic_cast转换符只能用于指针或者引用。dynamic_cast转换符只能用于含有虚函数的类。dynamic_cast转换操作符在执行类型转换时首先将检查能否成功转换,如果能成功转换则转换之, 如果转换失败,如果是指针则反回一个0值,如果是转换的是引用 ,则抛出一个bad_cast异常,所以在使用dynamic_cast转换之间应使用if语句对其转换成功与否进行测试,比如 pd = dynamic_cast(pb); if(pd){…}else{…} ,或者这样测试 if(dynamic_cast(pb)){…}else{…}

因此, dynamic_cast操作符一次执行两个操作 首先验证被请求的转换是否有效,只有转换有效,操作符才实际进行转换。基类的指针可以赋值为指向派生类的对象,同样,基类的引用也可以用派生类对象初始化,因此,dynamic_cast操作符执行的验证必须在运行时进行。

2、const_cast操作符
其表达式为  const_cast<类型>(表达式)

其中类型指要把表达式转换为的目标类型。该操作符用于改变const和volatile, const_cast最常用的用途就是删除const属性,如果某个变量在大多数时候是常量,而在某个时候又是需要修改的,这时就可以使用const_cast操作符了。
const_cast操作符不能改变类型的其他方面,他只能改变const或volatile,即const_cast不能把int改变为double,但可以把const int改变为int。const_cast只能用于指针或引用。

const_cast的用法举例
比如: int a=3; const int *b=&a; int* c=const_cast(b); *c=4; cout<<a<<*c;这时输出两个4,如果不使用const_cast转换符则常量指针*c的值是不能改变的,在这里使用const_cast操作符,通过指针b就能改变常量指针和变量a的值。

3、static_cast操作符
该操作符用于非多态类型的转换,任何标准转换都可以使用他,即static_cast可以把int转换为double,但不能把两个不相关的类对象进行转换,比如类A不能转换为一个不相关的类B类型。static_cast本质上是传统c语言强制转换的替代品。

static_cast(静态转换)执行非多态的转换,用于代替C中通常的转换操作。因此,被做为隐式类型转换使用。 显式告诉编译器,不关心转换后精度损失。比如:
int i;
float f = 166.7f;
i = static_cast<int>(f);
此时结果,i的值为166。

4、reinterpret_cast操作符
该操作符用于将一种类型转换为另一种不同的类型,比如可以把一个整型转换为一个指针,或把一个指针转换为一个整型,因此使用该操作符的危险性较高,一般不应使用该操作符。

reinterpret_cast(重述转换)主要是将数据从一种类型的转换为另一种类型。所谓“通常为操作数的位模式提供较低层的重新解释”也就是说将数据以二进制存在形式的重新解释。比如:
int i;
char *p = "This is a example.";
i = reinterpret_cast<int>(p);
此时结果,i与p的值是完全相同的。reinterpret_cast的作用是说将指针p的值以二进制(位模式)的方式被解释为整型,并赋给i, 一个明显的现象是在转换前后没有数位损失,即一定不改变元数据。 


关于reinterpret_cast,使用这个操作符的类型转换,其的转换结果几乎都是执行期定义(implementation-defined)。因此,使用reinterpret_casts的代码很难移植。 

reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。例如,假设你有一个函数指针数组

typedef void (*FuncPtr)(); // FuncPtr是一个指向函数的指针,该函数没有参数返回值类型为void

FuncPtr funcPtrArray[10]; // funcPtrArray是一个能容纳10个FuncPtrs指针的数组 


让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:

int doSomething();


你不能不经过类型转换而直接去做,因为doSomething函数对于funcPtrArray数组来说有一个错误的类型。在FuncPtrArray数组里的函数返回值是void类型,而doSomething函数返回值是int类型。

funcPtrArray[0]  =  &doSomething; // 错误!类型不匹配reinterpret_cast可以让你迫使编译器以你的方法去看待它们

funcPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething); // this compiles 

 

转换函数指针的代码是不可移植的(C++不保证所有的函数指针都被用一样的方法表示),在一些情况下这样的转换会产生不正确的结果。

from http://zhidao.baidu.com/question/110604232.html?fr=qrl&index=0&qbl=topic_question_0&word=staticcast%20dynamiccast

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值