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

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的转换则是允许的,结果是空指针。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值