dynamic_cast

本文详细介绍了C++中的dynamic_cast关键字,用于在类继承层次间进行安全的向下转型。dynamic_cast主要适用于多态类型,当尝试将基类指针或引用转换为派生类时,如果转换成功则返回对应类型,失败则返回空指针或抛出std::bad_cast异常。文中通过示例代码展示了dynamic_cast的使用场景及其行为。
摘要由CSDN通过智能技术生成

dynamic_cast

dynamic_cast主要用于“安全地向下转型”

dynamic_cast用于类继承层次间的指针或引用转换。主要用于执行“安全的向下转型”,对于向上转换,没有问题。

dynamic_cast<new_type>(expression)

new_type:指向完全类型的指针或引用,或者是指向void类型的指针

expression:如果new_type是引用,则expression是一个完全类类型的左值;如果new_type是指针,则expression是一个指向完全类类型的右值指针

如果转换成功,则dynamic_cast返回new_type类型的值。如果转换失败,并且new_type是指针,则返回空指针;如果new_type是引用,则返回std::bad_cast错误。

解释

dynamic_cast不涉及去除constvolatile

  • 如果expression是一个空指针,则转换的结果就是指向new_type的空指针。
  • 如果new_type是一个指向Base的指针/引用,expression是一个指向Derived的指针/引用,Base是唯一的,Derived可访问的基类。转换的结果就是expression指向/引用的子类对象的基类子对象。
  • 如果expression是一个指针/引用,指向多态类型基类,new_type是一个指针/引用,指向子类类型。
    • 如果,expression指向/引用一个derived对象的公共base部分,并且这个子类类型的对象来源于expression指向的derived对象,这个转换的结果是指向derived的指针/引用。
    • 如果,expression指向/引用一个最子类对象,这个最子类对象有唯一的derived的基类部分,这个转换的结果就是指向derived的指针/引用。
    • 否则,如果是指针,则返回指向new_type的空指针;引用的话,就返回std::bad_cast错误。
#include <iostream>
 
struct V {
    virtual void f() {}  // must be polymorphic to use runtime-checked dynamic_cast
};
struct A : virtual V {};
struct B : virtual V {
  B(V* v, A* a) {
    // casts during construction (see the call in the constructor of D below)
    dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B, results in B*
    dynamic_cast<B*>(a); // undefined behavior: a has type A*, A not a base of B
  }
};
struct D : A, B {
    D() : B(static_cast<A*>(this), this) { }
};
 
struct Base {
    virtual ~Base() {}
};
 
struct Derived: Base {
    virtual void name() {}
};
 
int main()
{
    D d; // the most derived object
    A& a = d; // upcast, dynamic_cast may be used, but unnecessary
    [[maybe_unused]]
    D& new_d = dynamic_cast<D&>(a); // downcast
    [[maybe_unused]]
    B& new_b = dynamic_cast<B&>(a); // sidecast
 
 
    Base* b1 = new Base;
    if(Derived* d = dynamic_cast<Derived*>(b1))
    {
        std::cout << "downcast from b1 to d successful\n";
        d->name(); // safe to call
    }
 
    Base* b2 = new Derived;
    if(Derived* d = dynamic_cast<Derived*>(b2))
    {
        std::cout << "downcast from b2 to d successful\n";
        d->name(); // safe to call
    }
 
    delete b1;
    delete b2;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值