动态转换基础到派生对象

时间:2015-03-10 00:07:43

标签: c++ inheritance polymorphism dynamic-cast

我试图将派生对象分配给基础对象的向量,然后将它们转换回派生对象。我虽然无法进行演员表。

struct Base
{
    string foo;
    virtual ~Base() {}
};

struct Derived : Base
{
    string bar;
};

我有一个修改基本元素向量的函数。根据某些条件,它可能会创建派生对象而不是基础对象,并将其推送到向量:

void foo(vector<Base> &bases)
{
    Base *base;
    if (...)
    {
        base = new Derived;
        base->foo = string("hello");
    }
    bases.push_back(*base) 
}

然后我将一个向量传递给该函数并尝试获取内容。

vector<Base> bases;
foo(bases);

for (auto it = bases.begin(); it != bases.end(); ++it)
{
    Base *base = &(*it);
    Derived *derived = dynamic_cast<Derived*>(base); 
    // derived == nullptr
}

我在这里缺少什么?如果我尝试访问foo作为Base对象,它可以工作,但是当我尝试动态转换为Derived对象时,尽管已在foo(vector<Base> &bases)函数中创建为Derived对象,但它仍然失败。

3 个答案:

答案 0 :(得分:2)

这不起作用:

void foo(vector<Base> &bases)
{
    Base *base;
    if (...)
    {
        base = new Derived;
        base->foo = string("hello");
    }
    bases.push_back(*base) 
}

vector<>包含对象,而不是引用。当push_back一个被理解为基类型的对象时,只存储适用于基类型的数据(即“切片”)。

相反,请在Base*中存储shared_ptr<Base>vector<>

值得注意的是,在上面的代码段中,每当跳过if()块时,您都会收到访问权限,因为base永远不会被初始化。

答案 1 :(得分:0)

问题是你不能直接对对象使用多态,你必须使用基础对象的POINTERS然后你可以转换为派生类或直接调用虚方法。

从以下位置更改您的系统:

vector<Base> bases;

vector<Base*> bases;

并根据此更新所有代码,一切都将完美运行:)

答案 2 :(得分:0)

您的向量包含Base类型的Base个对象。您可能通过复制派生类型来初始化它们;但所有这一切都是复制Base部分(有些人称之为切片),失去了对原始类型的任何了解。

多态性仅适用于引用或指针;您需要Base*才能管理派生类型的对象。如何管理对象本身的生命周期,无论是存储在其他地方,还是使用拥有它们的向量(最好是智能)指针,都可以作为练习。