您的位置:首页 > 编程语言 > C语言/C++

C++类型转化分析:动态态转换->dynamic_cast

2013-08-18 18:05 501 查看
dynamic_cast

static_cast可以实现子类到基类的安全转换,但是不能实现基类到子类的安全转换,那么如果想实现基类到子类的安全转换应该怎么处理呢?嗯是用dynamic_cast类型转换:
注意:

上行转换(子类到基类)是安全的,并且static_cast dynamic_cast是等效的

下行转换(基类到子类)static_cast转换是不安全的但是dynamic_cast转换是安全的

dynamic_cast被用来执行从基类到子类的安全转换,转换的类类型(基类)必须有虚函数,否则不能使用dynamic_cast

dynamic_cast<type-id>(expression)

如果type-id是void*类型,那么是expression类型。

如果type-id是非void*类型,那么运行时检查指向  expression  的对象能否转换为指向  type-id  类型的对象。

dynamic_cast指针例子:

class employee{

public:

    virtual int salary();

};

class manager:public employee{

public:

    int salary();

};

class programmer:public employee{

public:

    int salary();

    int bonus();

};

mytest(employee* pe){

    //如果pe指向的是programmer类型的对象,则转换成功。否则,失败,结果为0。

    programmer *pm = dynamic_cast<programmer*>(pe);

    if(pm){//在使用pm之前必须使用if语句来判断是否转换成功

        //可以用pm调用programmer::bonus()

    }

    else{

        //只能使用employee的成员的虚函数。

    }

}

因为存在空指针,所以mytest中可以使用if(pm)来判断转换是否有效。但是不存在空引用,因此不能比较dynamic_cast的结果是否为0来判断引用转换成功与否,但是会抛出bad_cast的异常。

mytest(employee& re){

    try{

        programmer& em = dynamic_cast<programmer&>(re);

        //用em调用bonus;

    }

    catch(std:: bad_cast)

    {

        //使用employee的成员函数

    }

}

例子总结:
1:

class A{};

class B{};

void func(){

    A* pa=new A;

    B* pb=new B;

    void* pv=dynamic_cast<void*>(pa);

    //pv就是一个A类型的对象了

    ......

    pv=dynamic_cast<void*>(pb);

    //pv就是一个B类型的对象了

    ......

}
2:

class B{};

class D:public B{};

void func(){

    B* pb=new D;

    B* pb2=new B;

    D* pd=dynamic_cast<D*>(pb);//ok 转换成功,pd是一个指向D的指针

    D* pd2=dynamic_cast<D*>(pb2);//转换失败但是编译通过,因为pd2指向的是null

}

为什么基类向子类转换会转换失败呢?因为基类向子类转换有可能会出现二义性。

另外:

dynamic_cast还支持交叉转换(cross cast)。如下代码所示。

class A{

public:

    int m_iNum;

    virtual void f(){}

};

class B:public A{

};

class D:public A{

};

void foo(){

    B *pb = new B;

    pb->m_iNum = 100;

    D *pd1 = static_cast<D*>(pb); //compile error

    D *pd2 = dynamic_cast<D*>(pb); //pd2 is NULL

    delete pb;

}

在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用 dynamic_cast的转换则是允许的,结果是空指针。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐