欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++ rtti判斷基類指針指向的真實對象類型

 更新時間:2023年08月28日 10:30:31   作者:會灰的飛貓  
這篇文章主要為大家介紹了c++ 判斷基類指針指向的真實對象類型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

在 c++ 面向?qū)ο笫褂弥?,我們常常會定義一個基類類型的指針,在運行過程中,這個指針可能指向一個基類類型的對象,也可能指向的是其子類類型的對象,那現(xiàn)在問題來了,我們?nèi)绾稳ヅ袛噙@個指針到底執(zhí)行了一個什么類型的對象呢?

今天我們就聊一下這個問題,首先我們要區(qū)分是否允許 RTTI,據(jù)此有不同辦法。

允許使用 RTTI

在打開 rtti 的場景下,可以使用 dynamic_cast 和 typeid 這兩個運算符來判斷對象的真實類型。

使用 dynamic_cast

dynamic_cast 用于在運行時進(jìn)行多態(tài)類型檢查和轉(zhuǎn)換,它可以將指向基類的指針轉(zhuǎn)換為指向派生類的指針或引用。如果轉(zhuǎn)換成功,則說明對象屬于目標(biāo)類或其派生類。如果轉(zhuǎn)換失敗,則返回空指針。
我們看如下例子,我們想判斷指針 basePtr 是否指向了 Child2 類型的對象??偣策M(jìn)行了兩次測試,第一次讓該指針指向了 Child1 類型的對象,第二次則是指向了 Child2 類型的對象。

#include <iostream>
class Basic {
public:
    virtual void say() {
        std::cout << "我是基類" << std::endl;
    }
};
class Child1 : public Basic {
public:
    void say() {
        std::cout << "我是 child 1" << std::endl;
    }
};
class Child2 : public Basic {
public:
    void say() {
        std::cout << "我是 child 2" << std::endl;
    }
};
int main()
{
    Basic* basePtr;
    basePtr = new Child1();
    if (dynamic_cast<Child2*>(basePtr)) {
        std::cout << "[test 1]指針指向了 Child2 類型對象" << std::endl;
    } else {
        std::cout << "[test 1]指針沒有指向 Child2 類型對象" << std::endl;
    }
    delete basePtr;
    basePtr = new Child2();
    if (dynamic_cast<Child2*>(basePtr)) {
        std::cout << "[test 2]指針指向了 Child2 類型對象" << std::endl;
    } else {
        std::cout << "[test 2]指針沒有指向 Child2 類型對象" << std::endl;
    }
    delete basePtr;
}

讓我們一起看看兩次的打印,這是符合我們的預(yù)期的,使用 dynamic_cast 可以判斷一個基類類型的指針是否指向了某個具體類類型。

在這里,有的朋友會好奇,我為什么添加了 say() 這么一個方法,湊數(shù)嗎?確實是,就是湊數(shù)的dynamic_cast 是用于多態(tài)運行時的類型檢查,如果我不增加這么一個方法,并且在基類中添加上 virtual 關(guān)鍵字,那就不存在多態(tài),也就無從談起運行時多態(tài)類型檢查。下面是我將 virtual 去掉,或者干脆刪除 say() 方法的編譯結(jié)果。

使用 typeid

typeid 運算符返回一個 type_info 對象,該對象包含類型的相關(guān)信息。通過比較兩個指針的類型信息,可以確定它們是否具有相同的類型。這里我們不用管 type_info 是什么東西,我們主要看看怎么用,下面繼續(xù)看看剛剛的例子。

#include <iostream>
class Basic {
public:
    virtual void say() {
        std::cout << "我是基類" << std::endl;
    }
};
class Child1 : public Basic {
public:
    void say() {
        std::cout << "我是 child 1" << std::endl;
    }
};
class Child2 : public Basic {
public:
    void say() {
        std::cout << "我是 child 2" << std::endl;
    }
};
int main()
{
    Basic* basePtr;
    basePtr = new Child1();
    if (typeid(*basePtr) == typeid(Child2)) {
        std::cout << "[test 1]指針指向了 Child2 類型對象" << std::endl;
    } else {
        std::cout << "[test 1]指針沒有指向 Child2 類型對象" << std::endl;
    }
    delete basePtr;
    basePtr = new Child2();
    if (typeid(*basePtr) == typeid(Child2)) {
        std::cout << "[test 2]指針指向了 Child2 類型對象" << std::endl;
    } else {
        std::cout << "[test 2]指針沒有指向 Child2 類型對象" << std::endl;
    }
    delete basePtr;
}

運行結(jié)果,和剛剛使用 dynamic_cast 一樣。我們這里是來判斷基類指針是否指向了某個具體類對象,typeid 當(dāng)然也可以用來判斷兩個指針指向的具體類類型是否相同,這里不再展開。

值得注意的是,使用 typeid 時,如果去掉基類方法中的 virtual 關(guān)鍵字,編譯并不會報錯,但運行結(jié)果肯定會錯,此時因為不存在多態(tài),該運算符始終會返回基類的信息。

不允許使用 RTTI

出于某些原因,你的項目可能禁用了 RTTI,那這個時候我們應(yīng)該怎么判斷基類指針指向的具體類呢?我們還能利用多態(tài)本身,就是給基類新增一個虛方法,子類在必要的時候來重寫。

下面我們繼續(xù)用剛剛的例子,一起看看代碼吧。

#include <iostream>
class Basic {
public:
    virtual void say() {
        std::cout << "我是基類" << std::endl;
    }
    virtual bool isChild2() {
        return false;
    }
};
class Child1 : public Basic {
public:
    void say() {
        std::cout << "我是 child 1" << std::endl;
    }
};
class Child2 : public Basic {
public:
    void say() {
        std::cout << "我是 child 2" << std::endl;
    }
    bool isChild2() {
        return true;
    }
};
int main()
{
    Basic* basePtr;
    basePtr = new Child1();
    if (basePtr->isChild2()) {
        std::cout << "[test 1]指針指向了 Child2 類型對象" << std::endl;
    } else {
        std::cout << "[test 1]指針沒有指向 Child2 類型對象" << std::endl;
    }
    delete basePtr;
    basePtr = new Child2();
    if (basePtr->isChild2()) {
        std::cout << "[test 2]指針指向了 Child2 類型對象" << std::endl;
    } else {
        std::cout << "[test 2]指針沒有指向 Child2 類型對象" << std::endl;
    }
    delete basePtr;
}

我們新增了一個 isChild2() 的方法,用來判斷該類是否是 Child2 類型,因為我這里只需要判斷基類指針是否指向了 Child2 類型的對象,所以就直接增加了個 bool 返回值的接口進(jìn)行判斷了。在實際使用時,也可以返回枚舉變量,分別對應(yīng)例子中的三個類。

總結(jié)

當(dāng)項目允許 RTTI 時,我們可以使用 dynamic_cast 和 typeid 運算符來判斷一個基類指針指向的具體對象類型;當(dāng)禁用 RTTI 時,我們就利用多態(tài)本身,為基類新增一個方法,用來獲取類類型信息。

以上就是c++ rtti判斷基類指針指向的真實對象類型的詳細(xì)內(nèi)容,更多關(guān)于c++ rtti判斷基類指針指向的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • AVX2指令集優(yōu)化浮點數(shù)組求和算法

    AVX2指令集優(yōu)化浮點數(shù)組求和算法

    這篇文章主要為大家介紹了AVX2指令集優(yōu)化浮點數(shù)組求和算法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • C++面試八股文之override和finial關(guān)鍵字有何作用

    C++面試八股文之override和finial關(guān)鍵字有何作用

    C++11中的override和final關(guān)鍵字是為了增強代碼的編譯時類型檢查和面向?qū)ο笤O(shè)計中的繼承機(jī)制,下面這篇文章主要給大家介紹了關(guān)于C++面試八股文之override和finial關(guān)鍵字有何作用的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • vs2019中使用MFC構(gòu)建簡單windows窗口程序

    vs2019中使用MFC構(gòu)建簡單windows窗口程序

    今天發(fā)現(xiàn)網(wǎng)上好多MFC代碼都不能用,給大家分享一個簡單的MFC窗口語言,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C++按位異或運算符的使用介紹

    C++按位異或運算符的使用介紹

    本篇文章對C++按位異或運算符的使用進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下
    2013-05-05
  • C++基于CreateToolhelp32Snapshot獲取系統(tǒng)進(jìn)程實例

    C++基于CreateToolhelp32Snapshot獲取系統(tǒng)進(jìn)程實例

    這篇文章主要介紹了C++基于CreateToolhelp32Snapshot獲取系統(tǒng)進(jìn)程實例,是Windows應(yīng)用程序設(shè)計中非常實用的技巧,需要的朋友可以參考下
    2014-10-10
  • C語言實現(xiàn)井字棋游戲(人機(jī)對弈)

    C語言實現(xiàn)井字棋游戲(人機(jī)對弈)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)井字棋人機(jī)對弈游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 關(guān)于vs strcpy_s()和strcat_s()用法探究

    關(guān)于vs strcpy_s()和strcat_s()用法探究

    這篇文章主要介紹了關(guān)于vs strcpy_s()strcat_s()用法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • 深入了解c++11 移動語義與右值引用

    深入了解c++11 移動語義與右值引用

    這篇文章主要介紹了c++ 移動語義與右值引用的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-08-08
  • opencv學(xué)習(xí)筆記C++繪制灰度直方圖

    opencv學(xué)習(xí)筆記C++繪制灰度直方圖

    這篇文章主要為大家介紹了opencv學(xué)習(xí)筆記C++繪制灰度直方圖的實現(xiàn)代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • C++ 中 vector 的常用操作方法匯總

    C++ 中 vector 的常用操作方法匯總

    在C++的STL中,vector是一個動態(tài)數(shù)組,可以在運行時調(diào)整大小,本文介紹了vector的初始化、元素訪問、修改、迭代器操作、容量管理以及性能優(yōu)化技巧,通過這些操作,可以有效地使用vector管理數(shù)據(jù),本文介紹C++  vector 操作,感興趣的朋友一起看看吧
    2024-10-10

最新評論