繁体   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