簡體   English   中英

指向包含基類和派生類 class 對象的指針的向量 - 訪問派生類特定變量

[英]Vector of pointers to base class containing base and derived class objects - accessing derived-class specific variables

我一直在努力解決這個C++問題。 我已經創建了基類 object class 和派生類 object class 並且我試圖將對基類和派生對象的引用存儲在基類指針的向量中(避免 object 切片)。 使用指針,我可以運行虛方法,並且可以確認指針指向派生類 object,但是我無法獲得派生類 class 的特定變量。 有什么辦法嗎?

基地 class object:

class Base
{

public:

    Manager* manager;

    Base(){}
    Base(Manager* mManager){
        manager = mManager;
    }

    virtual void init(){}

    virtual void speak() {
        std::cout << "Base class is speaking!" << std::endl;
    }

};

導出 class object:

class Derived : public Base
{

public:

    Manager* manager;

    int DerviedVariable = 100;

    Derived(){}
    Derived(Manager* mManager){
        manager = mManager;
    }

    void speak() override {
        std::cout << "Derived class is speaking!" << std::endl;
    }

};

這些對象(Base na Derived)是使用Manager class和名為groupedEntities 的數組創建和存儲的:


constexpr std::size_t maxGroups = 32;
using Group = std::size_t;

class Manager
{
public:

    std::array<std::vector<Base*>, maxGroups> groupedEntities;

    void addToGroup(Base* mBase, Group mGroup)
    {
        groupedEntities[mGroup].emplace_back(mBase);
    }


    std::vector<Base*>& getGroup(Group mGroup)
    {
        return groupedEntities[mGroup];
    }

    template <typename T, typename... TArgs>
    T* addEnt(TArgs&&... mArgs)
    {
        T* e(new T(this));
        return e;
    }

};

我正在創建對象並嘗試像這樣引用它們:

void main() {

    std:size_t groupBlob = 0u;

    Manager* manager = new Manager();
    Derived* blob1(manager->addEnt<Derived>());
    Derived* blob2(manager->addEnt<Derived>());


    manager->addToGroup(blob1, groupBlob);
    manager->addToGroup(blob2, groupBlob);


    auto& grouped(manager->getGroup(groupBlob));

    for (auto& e : grouped)
    {
        e->speak();
        std::cout << e.DerviedVariable ;

    }


}

不幸的是, e.DerviedVariable是不可訪問的,而speak() function 說“Dervied class 正在說話”。 有什么方法可以用這種架構訪問派生類變量嗎? 謝謝

是的,有可能。 您只需要投射指針。 最簡單的語法是:

((Derived*)e)->DerviedVariable

這等同於 C++ish

static_cast<Derived*>(e)->DerviedVariable

這里的“靜態”一詞提醒您沒有運行時檢查:編譯器相信您e確實指向Derived的一個實例。 如果沒有,則會發生未定義的行為。 更安全的選擇是dynamic_cast

Derived *ee = dynamic_cast<Derived*>(e);
if (ee)
    x = ee->DerviedVariable;

如果 object 不是Derived的實例,它會返回 NULL。 (請注意,也可以轉換引用,但由於沒有 NULL 引用,如果無法轉換,則dynamic_cast將拋出)

然而,出於某種原因,使用此類轉換通常被認為是一種不好的做法。 虛函數更可取,主要是因為使用它們不需要您甚至知道調用點的實際 object 類型。

在這種情況下,您可以使用dynamic_cast 表達式dynamic_cast<Derived*>(e)其中eBase*類型,如果e實際上指向Derived類型的 object,則計算結果為Derived* ,否則它將計算為 null 指針。

if(Derived* d = dynamic_cast<Derived*>(e)) {
    std::cout << d->e.DerviedVariable;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM