根據基類指針判斷指針指向的子類

近期突然自己想到了一個問題:如果我現在有一個基類,它有很多個子類。同時現在又有一個基類指針,它指向一個子類,但是我不知道其具體是哪一個子類,所以如果我想知道它實際指向哪個子類在java中可以有instanceof可以實現,而在C++中怎麼實現呢?

後來我想了一段時間,終於想明白了,在C++中如果想在運行而不是在編譯的過程中獲得對象的具體的類型,那麼就必須要用到虛函數。其實虛函數的出現就可以理解爲需要在運行的時候知道對象的具體類型,反之亦然。既然用到了虛函數,那麼就可以實用dynamic_cast<>()函數來判斷指針或者引用的具體類類型了,於是我下了下面的代碼作爲例子,其類的關係如圖:


代碼如下:

#include <iostream>
using namespace std;

class A
{
public:
    A(){}
    virtual ~A(){}
    
};

class B:public A
{
public:
    
    B(){}
    ~B(){}
    
};

class C:public A
{
public:
    C(){}
    ~C(){}
    
};

class D:public A
{
public:
    D(){}
    ~D(){}
};

int main(int argc, const char * argv[]) {
    A* pa = new D();
    if((dynamic_cast< B* >( pa )) != nullptr){
        cout<<"此類爲B"<<endl;
    }else if((dynamic_cast<C*>(pa)) != nullptr){
        cout<<"此類爲C"<<endl;
    }else if((dynamic_cast<D*>(pa)) != nullptr){
        cout<<"此類爲D"<<endl;
    }
    delete pa;
    return 0;
}
注意到上面的代碼中,我把基類的析構函數設爲虛函數。

接着我又想,如果我不是使用虛函數,那麼就不能使用dynamic_cast<>()函數來判斷了,因爲使用dynamic_cast<>()函數中的指針或者引用對應的類中至少要含有一個虛函數。經過我查閱網上的資料,發現如果你允許類有虛函數的話,可以通過在基類中添加虛函數類實現判斷指針所指向的真正子類;如果類中不允許出現虛函數,那麼你只能在每個類中實現類似於getType()的函數,讓它返回能表示所有類類型的枚舉類型(這裏介紹一個stackoverflow上的回答點擊打開鏈接)。當然,一般不會出現後者的情況,我還是建議再用前者的方法,最簡單的方式就是將析構函數設置成虛函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章