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;