gpt4 book ai didi

c++ - 迭代子类错误列表

转载 作者:搜寻专家 更新时间:2023-10-31 00:37:48 24 4
gpt4 key购买 nike

我是 C++ 的新手,并且有 C# 背景,我在处理这个列表迭代时遇到了问题:

我有一个方法可以遍历对象列表并为每个对象调用一个更新方法,效果很好。该列表的类型为 std::list<EngineComponent>并称为 engineComponents .

void Game::Update()
{
for (EngineComponent component: this->engineComponents)
{
component.Update();
}
}

我还有一个 EngineComponent 的子类称为 DrawableEngineComponent .

当我尝试进行类似的迭代时出现问题:

void Game::Draw()
{
for (DrawableEngineComponent component: this->engineComponents)
{
component.Draw();
}
}

这会产生错误“不存在从‘EngineComponent’到‘DrawableEngineComponent’的合适的用户定义转换”。鉴于此实现在 C# 中一切都很好而且花花公子,我真的不确定如何最好地在 C++ 中解决这个问题。

我可以想到一些可行/应该可行的替代方法,但我想知道 C++ 中是否有功能以类似于 C# 的方式执行此操作,而无需手动定义转换。

这两个类的定义如下:

class EngineComponent
{
public:
EngineComponent(void);
~EngineComponent(void);

virtual void Update(void);
};


class DrawableEngineComponent : public EngineComponent
{
public:
DrawableEngineComponent(void);
~DrawableEngineComponent(void);

virtual void Draw(void);
};

是的,我正在稍微复制 XNA 框架 ;)

最佳答案

你得到这个错误的真正原因是你定义基于范围的方式,你通过复制而不是引用来检索对象:

for (EngineComponent component: this->engineComponents)
{
// component is a copy of the object in the list
}

EngineComponent 是父类(super class),因此不会隐式转换为派生类。如果您尝试从 EngineComponent 列表中复制一个 DrawableEngineComponent,编译器无法知道源对象是否真的是派生类。

标准容器并不能很好地处理多态对象。一个更好的解决方案是使用 std::shared_ptr 来存储指向对象的指针。

std::list<std::shared_ptr<EngineComponent>> myList;
myList.push_back(std::make_shared<DrawableEngineComponent>());

这会将一个 DrawableEngineComponent 包裹在一个共享指针中,并将其存储在列表中。可以通过与您的原始方法类似的方式访问它:

for (auto& component: engineComponents)
{
component->Update();
}

但是这次您有一个可以调用的完全多态对象。如果对象在子类中重载了 Update() 方法,那么将调用 this。如果需要的话,您还可以使用强制转换来获取指向子类的指针:

for (auto& component: engineComponents)
{
auto pDrawComponent = dynamic_cast<DrawableEngineComponent*>(component.get());
if (pDrawComponent)
{
// it's drawable
}
}

关于c++ - 迭代子类错误列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19202846/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com