C++ 强制类型转换符

C++有四种强制类型转换符,分别是dynamic_cast , static_cast,reinterpret_cast, const_cast

1.     dynamic_cast

该运算符用于将一个指向派生类的基类指针或引用转换为派生类的指针或引用

表达式: dynamic_cast<目标类型>(表达式)

 

举例:

B*b; //含有虚函数的基类B

D*d, pd; //从B类派生出的派生类D

b= &pd; //指向派生类的基类指针b

d= dynamic_cast<D *>(b); //将b转化为派生类指针,将这个指针赋值给指针d

 

有人好奇为什么要这样做?为什么不直接d = &pd?

答:因为有时候需要强制类型转换。如果一个指向派生类的基类指针想访问派生类中除虚函数以外的成员,就需要将此基类指针转换为派生类指针。

例如,派生类D中有成员函数g(),可以采用dynamic_cast<D*>(b)->g()访问。

但是该语句不影响原来的指针的类型,即基类指针pb仍然是指向基类B的。如果单独使用该指针仍然不能访问派生类中特有的成员。

 

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{…}

 

 

2.     static_cast

表达式: static_cast <type-id > ( expression )

 

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。

 

用法:

用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。

用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。

把空指针转换成目标类型的空指针。

把任何类型的表达式转换成void类型。

注意:static_cast不能转换掉expressionconstvolatile、或者__unaligned属性。

题目:

class ClassA

{

    public:

    virtual ~ ClassA()

    {

    }

    virtual void FunctionA()

    {

    }

};

class ClassB

{

    public:

    virtual void FunctionB()

    {

    }

};

class ClassC: public ClassA, public ClassB

{

    public:

};

ClassC aObject;

ClassA *pA = &aObject;

ClassB *pB = &aObject;

ClassC *pC = &aObject;

假设定义了ClassA* pA2,下面正确的代码是:

正确答案: B D   

A.  pA2=static_cast<ClassA*>(pB);

B.  void* pVoid=static_cast<void*>(pB);

pA2=static_cast<ClassA*>(pVoid);

C.  pA2=pB;

D.  pA2=static_cast<ClassA*>(static_cast<ClassC*>(pB));

 

解析:

A   两个无关类型指针之间的转换是不合法的

B  通过void*这个媒介,合法

C  直接赋值,无法进行隐式转换,不合法

D  通过继承体系中的一个做媒介,上行下行合法

 

3.      reinterpret_cast操作符

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

 

reinterpret_cast(重述转换)主要是将数据从一种类型的转换为另一种类型。所谓通常为操作数的位模式提供较低层的重新解释也就是说将数据以二进制存在形式的重新解释。比如:

int i;

char *p = "This is a example.";

i = reinterpret_cast<int>(p);

此时结果,ip的值是完全相同的。reinterpret_cast的作用是说将指针p的值以二进制(位模式)的方式被解释为整型,并赋给i一个明显的现象是在转换前后没有数位损失,即一定不改变元数据。 

from http://blog.sina.com.cn/s/blog_8fcf831b0101auaa.html

 

 

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

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

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

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

 

让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入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

 

 

4.      const_cast操作符

其表达式为 const_cast<类型>(表达式)

 

其中类型指要把表达式转换为的目标类型。该操作符用于改变constvolatileconst_cast最常用的用途就是删除const属性,如果某个变量在大多数时候是常量,而在某个时候又是需要修改的,这时就可以使用const_cast操作符了。

const_cast操作符不能改变类型的其他方面,他只能改变constvolatile,即const_cast不能把int改变为double,但可以把const int改变为intconst_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的值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值