dynamic_cast使用方式

来源:互联网 发布:网络视频课怎么刷 编辑:程序博客网 时间:2024/05/18 12:40

        

        c++提供了四种新的cast机制,分别为static_cast, const_cast, dynamic_cast和reinterpret_cast。虽然也支持c中使用一对圆括号来cast,但是由于c++与c最大的区别是c++增加了类的概念,因此在子类与父类之间进行cast的时候,使用c的cast方式是无法保证其正确性的,因此c++提供了新的cast机制(虽然比较丑陋而且需要敲打更多的code,但是提供了安全性):dynamic_cast。

        对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。因此可以用来在运行期间进行类型判断。如下述演示代码。

   


class CShape{...}
class CCircle:public CShape{...}
class CRectangle: public CShape{...}

CShape 
* pShape;
... 
//do something

if (dynamic_cast<CCircle * > (pShape))
{
    
//process the Circle object
}

else if (dynamic_cast<CRectangle * > (pShape))
{
    
//process the Rectangle object
}

else
{
    
//error, just shape object
}

       如下面代码所示,将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理,即会作一定的判断。由于这会用到RTTI技术,因此需要启动“运行时类型信息”这一选项,而在VC.net 2003中默认是关闭的,所以需要人为的启动这一选项,如图1所示。否则编译器会报下面的警告:

warning C4541: “dynamic_cast”用在了带 /GR- 的多态类型“CBasic”上;可能导致不可预知的行为

从而导致程序在运行时发生异常。

但是dynamic_cast在将父类cast到子类时,父类必须要有虚函数。例如在图1中的代码中将CBasic类中的test函数不定义成virtual时,编译器会报错:
error C2683: dynamic_cast : CBasic”不是多态类型
这是由于有了多态后,将子类对象赋值给父类对象才有意义。这样子类与父类之间的cast才有意义。
        当然如果使用dynamic_cast来直接将子类cast到父类(向上cast),那就无所谓了。即父类不需要一定有虚函数,也不需要开启“运行时类型信息”这一选项。

#include 
<iostream>
using namespace std;

class CBasic
{
public:
     
virtual int test(){return 0;}
}
;

class CDerived : public CBasic
{
public:
    
virtual int test(){    return 1;}
}
;

int main()
{
    CBasic        cBasic;
    CDerived    cDerived;
    
    CBasic 
* pB1 = new CBasic;
    CBasic 
* pB2 = new CDerived;

//dynamic cast failed, so pD1 is null.
    CDerived * pD1 = dynamic_cast<CDerived * > (pB1);   
                
//dynamic cast succeeded, so pD2 points to  CDerived object                                        
    CDerived * pD2 = dynamic_cast<CDerived * > (pB2);   
    
//dynamci cast failed, so throw an exception.            
//    CDerived & rD1 = dynamic_cast<CDerived &> (*pB1);   

//dynamic cast succeeded, so rD2 references to CDerived object.
    CDerived & rD2 = dynamic_cast<CDerived &> (*pB2);   

    
return 0;
}

                                         图  1  启动“运行时类型信息”选项
原创粉丝点击