C++ Gossip: 使用 dynamic_cast

原文链接:http://openhome.cc/Gossip/CppGossip/dynamicCast.html

您可以使用static_cast(甚至是傳統的C轉型方式)將基底類別指標轉換為衍生類別指標,這種轉型方式是強制轉型,在執行時期使用強制轉型有危險 性,因為編譯器無法得知轉型是否正確,執行時期真正指向的物件型態是未知的,透過簡單的檢查是避免錯誤的一種方式:

if(typeid(*base) == typeid(Derived1)) {
    Derived1 *derived1 = static_cast<Derived1*>(base);
    derived1->showOne();
}

為了支援執行時期的型態轉換動作,C++提供了dynamic_cast用來將一個基底類別的指標轉型至衍生類別指標,稱之為「安全向下轉型」(Safe downcasting),它在執行時期進行型態轉換動作,首先會確定轉換目標與來源是否屬同一個類別階 層,接著才真正進行轉換的動作,檢驗動作在執行時期完成,如果是一個指標,則轉換成功時傳回位址,失敗的話會傳回0,如果是參考的話,轉換失敗會丟出 bad_cast例外。

可以將 執行時期型態資訊(RTTI) 中的showWho()函式如下修改:
void showWho(Base *base) {
    base->foo();
    
    if(Derived1 *derived1 = dynamic_cast<Derived1*>(base)) {
        derived1->showOne();
    }
    else if(Derived2 *derived2 = static_cast<Derived2*>(base)) {
        derived2->showTwo();    
    } 
}

由於dynamic_cast轉換失敗的話會傳回0,因而運算的結果不可使用,必須先行對轉換結果作檢查才可以,如上例所示。

如果使用參考的話,dynamic_cast在轉換失敗之後會丟出bad_cast例外,所以您必須使用try...catch來處理例外,例如:
 

#include <iostream> 
#include <typeinfo> 
using namespace std; 

class Base { 
public: 
    virtual void foo() = 0;
}; 

class Derived1 : public Base { 
public: 
    void foo() { 
        cout << "Derived1" << endl; 
    } 
 
    void showOne() {
        cout << "Yes! It's Derived1." << endl;
    }
}; 

class Derived2 : public Base { 
public: 
    void foo() { 
        cout << "Derived2" << endl; 
    } 
 
    void showTwo() {
        cout << "Yes! It's Derived2." << endl;
    }
}; 

void showWho(Base &base) {
    try {
        Derived1 derived1 = dynamic_cast<Derived1&>(base);
        derived1.showOne();
    }
    catch(bad_cast) {
        cout << "bad_cast 轉型失敗" << endl;
    }
}

int main() { 
    Derived1 derived1;
    Derived2 derived2; 

    showWho(derived1);
    showWho(derived2);
 
    return 0;
}

執行結果:

Yes! It's Derived1.
bad_cast 轉型失敗


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值