最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++ rtti判斷基類(lèi)指針指向的真實(shí)對(duì)象類(lèi)型

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

正文

在 c++ 面向?qū)ο笫褂弥校覀兂3?huì)定義一個(gè)基類(lèi)類(lèi)型的指針,在運(yùn)行過(guò)程中,這個(gè)指針可能指向一個(gè)基類(lèi)類(lèi)型的對(duì)象,也可能指向的是其子類(lèi)類(lèi)型的對(duì)象,那現(xiàn)在問(wèn)題來(lái)了,我們?nèi)绾稳ヅ袛噙@個(gè)指針到底執(zhí)行了一個(gè)什么類(lèi)型的對(duì)象呢?

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

允許使用 RTTI

在打開(kāi) rtti 的場(chǎng)景下,可以使用 dynamic_cast 和 typeid 這兩個(gè)運(yùn)算符來(lái)判斷對(duì)象的真實(shí)類(lèi)型。

使用 dynamic_cast

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

#include <iostream>
class Basic {
public:
    virtual void say() {
        std::cout << "我是基類(lèi)" << 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 類(lèi)型對(duì)象" << std::endl;
    } else {
        std::cout << "[test 1]指針沒(méi)有指向 Child2 類(lèi)型對(duì)象" << std::endl;
    }
    delete basePtr;
    basePtr = new Child2();
    if (dynamic_cast<Child2*>(basePtr)) {
        std::cout << "[test 2]指針指向了 Child2 類(lèi)型對(duì)象" << std::endl;
    } else {
        std::cout << "[test 2]指針沒(méi)有指向 Child2 類(lèi)型對(duì)象" << std::endl;
    }
    delete basePtr;
}

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

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

使用 typeid

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

#include <iostream>
class Basic {
public:
    virtual void say() {
        std::cout << "我是基類(lèi)" << 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 類(lèi)型對(duì)象" << std::endl;
    } else {
        std::cout << "[test 1]指針沒(méi)有指向 Child2 類(lèi)型對(duì)象" << std::endl;
    }
    delete basePtr;
    basePtr = new Child2();
    if (typeid(*basePtr) == typeid(Child2)) {
        std::cout << "[test 2]指針指向了 Child2 類(lèi)型對(duì)象" << std::endl;
    } else {
        std::cout << "[test 2]指針沒(méi)有指向 Child2 類(lèi)型對(duì)象" << std::endl;
    }
    delete basePtr;
}

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

值得注意的是,使用 typeid 時(shí),如果去掉基類(lèi)方法中的 virtual 關(guān)鍵字,編譯并不會(huì)報(bào)錯(cuò),但運(yùn)行結(jié)果肯定會(huì)錯(cuò),此時(shí)因?yàn)椴淮嬖诙鄳B(tài),該運(yùn)算符始終會(huì)返回基類(lèi)的信息。

不允許使用 RTTI

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

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

#include <iostream>
class Basic {
public:
    virtual void say() {
        std::cout << "我是基類(lèi)" << 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 類(lèi)型對(duì)象" << std::endl;
    } else {
        std::cout << "[test 1]指針沒(méi)有指向 Child2 類(lèi)型對(duì)象" << std::endl;
    }
    delete basePtr;
    basePtr = new Child2();
    if (basePtr->isChild2()) {
        std::cout << "[test 2]指針指向了 Child2 類(lèi)型對(duì)象" << std::endl;
    } else {
        std::cout << "[test 2]指針沒(méi)有指向 Child2 類(lèi)型對(duì)象" << std::endl;
    }
    delete basePtr;
}

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

總結(jié)

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

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

相關(guān)文章

  • C++11生成隨機(jī)數(shù)(random庫(kù))的使用

    C++11生成隨機(jī)數(shù)(random庫(kù))的使用

    隨機(jī)數(shù)在很多地方都可以用到,本文主要介紹了C++11生成隨機(jī)數(shù)(random庫(kù))的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • QT5.12連接MySQL的實(shí)現(xiàn)

    QT5.12連接MySQL的實(shí)現(xiàn)

    本文主要介紹了QT5.12連接MySQL的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • C++棧實(shí)現(xiàn)逆波蘭式的應(yīng)用

    C++棧實(shí)現(xiàn)逆波蘭式的應(yīng)用

    逆波蘭式指的是操作符在其所控制的操作數(shù)后面的表達(dá)式。本文主要介紹了C++棧實(shí)現(xiàn)逆波蘭式的應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C/C++實(shí)現(xiàn)獲取完整路徑下的文件名及后綴

    C/C++實(shí)現(xiàn)獲取完整路徑下的文件名及后綴

    這篇文章主要為大家詳細(xì)介紹了C/C++實(shí)現(xiàn)獲取完整路徑下的文件名及后綴的完整方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-11-11
  • C++中function的實(shí)現(xiàn)原理詳解

    C++中function的實(shí)現(xiàn)原理詳解

    類(lèi)模版std::function是一種通用、多態(tài)的函數(shù)封裝。function的實(shí)例可以對(duì)任何可以調(diào)用的目標(biāo)實(shí)體進(jìn)行存儲(chǔ)、復(fù)制、和調(diào)用操作。本文主要聊聊它的實(shí)現(xiàn)原理,需要的可以參考一下
    2022-12-12
  • Visual Studio Code 2020安裝教程及CPP環(huán)境配置(教程圖解)

    Visual Studio Code 2020安裝教程及CPP環(huán)境配置(教程圖解)

    這篇文章主要介紹了Visual Studio Code 2020安裝教程、CPP環(huán)境配置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 關(guān)于C++函數(shù)模版的實(shí)現(xiàn)講解

    關(guān)于C++函數(shù)模版的實(shí)現(xiàn)講解

    今天小編就為大家分享一篇關(guān)于關(guān)于C++函數(shù)模版的實(shí)現(xiàn)講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • C語(yǔ)言實(shí)現(xiàn)socket簡(jiǎn)單通信實(shí)例

    C語(yǔ)言實(shí)現(xiàn)socket簡(jiǎn)單通信實(shí)例

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)socket簡(jiǎn)單通信的方法,是學(xué)習(xí)C語(yǔ)言網(wǎng)絡(luò)編程非?;A(chǔ)而又實(shí)用的實(shí)例,需要的朋友可以參考下
    2014-09-09
  • C++利用LuaIntf調(diào)用Lua的方法示例

    C++利用LuaIntf調(diào)用Lua的方法示例

    這篇文章主要給大家介紹了關(guān)于C++利用LuaIntf調(diào)用Lua以及利用lua-intf來(lái)調(diào)用C++函數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-11-11
  • 基于C程序啟動(dòng)代碼的深入分析

    基于C程序啟動(dòng)代碼的深入分析

    本篇文章是對(duì)C程序啟動(dòng)的代碼進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論

五大连池市| 洛隆县| 喀喇沁旗| 宝兴县| 青岛市| 六安市| 雅安市| 庆城县| 韶关市| 凤城市| 凤山市| 缙云县| 昭苏县| 恩施市| 湟源县| 德兴市| 丹寨县| 英超| 云安县| 延庆县| 荔浦县| 台东县| 阿克陶县| 鹤峰县| 凤山县| 尼玛县| 屯门区| 出国| 泸溪县| 梁河县| 林口县| 翁源县| 和林格尔县| 南部县| 渝北区| 塔河县| 遂川县| 禹城市| 西华县| 信阳市| 清流县|