C++ 将基础对象动态转换为派生对象

C++ 将基础对象动态转换为派生对象,c++,inheritance,polymorphism,dynamic-cast,C++,Inheritance,Polymorphism,Dynamic Cast,我试图将派生对象指定给基本对象的向量,然后将它们投射回派生对象。不过我不能演这个角色 struct Base { string foo; virtual ~Base() {} }; struct Derived : Base { string bar; }; 我有一个函数可以修改基本元素的向量。根据某些条件,它可能会创建衍生对象而不是基础对象,并将其推送到向量上: void foo(vector<Base> &bases) { Base *

我试图将派生对象指定给基本对象的向量,然后将它们投射回派生对象。不过我不能演这个角色

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) 
}
void foo(向量和基)
{
基地*基地;
如果(…)
{
基数=新导出的;
base->foo=string(“hello”);
}
底座。向后推(*底座)
}
然后我将一个向量传递给该函数,并尝试获取内容

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(基地);;
for(auto it=bases.begin();it!=bases.end();+it)
{
基数*基数=&(*it);
派生*派生=动态_铸造(基础);
//派生==nullptr
}
我错过了什么?如果我尝试将
foo
作为基本对象访问,它会工作,但当我尝试动态转换为派生对象时,它会失败,尽管它是在
foo(向量和基本)
函数中作为派生对象创建的。

这不起作用:

void foo(vector<Base> &bases)
{
    Base *base;
    if (...)
    {
        base = new Derived;
        base->foo = string("hello");
    }
    bases.push_back(*base) 
}
void foo(向量和基)
{
基地*基地;
如果(…)
{
基数=新导出的;
base->foo=string(“hello”);
}
底座。向后推(*底座)
}
vector
包含对象,而不是引用。当您
推回
理解为基本类型的对象时,仅存储适用于基本类型的数据(即“切片”)

相反,将
Base*
shared_ptr
存储在
向量中


还值得注意的是,在上面的代码片段中,只要跳过
if()
块,就会出现访问冲突,因为
base
从未初始化过。

问题在于不能直接对对象使用多态性,您必须使用基本对象的指针,然后才能强制转换到派生类或直接调用虚拟方法

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

vector<Base> bases;
向量基;

向量基;

并在此基础上更新所有代码,一切都将完美运行:)

向量包含
base
对象,类型为
base
。您可以通过复制派生类型来初始化这些类型;但是所做的只是复制
Base
部分(有些人称之为切片),丢失了对原始类型的任何知识


多态性只适用于引用或指针;您需要一个
Base*
来管理派生类型的对象。如何管理对象本身的生命周期,或者存储在其他地方,或者向量的指针(最好是智能指针)拥有这些对象,这只是一个练习。

如果不能使用
vector
,那么最后将切片放入其中的
派生的
对象。改为使用
vector
。“一切都会很好地工作”-除了需要将对象存储在某个地方并管理它们的生命周期之外。“…在此基础上更新所有代码…”可以概括为;)
vector<Base*> bases;