C++ 多态性 - 继承类的映射

C++ Polymorphism - Map of inherited classes

本文关键字:映射 继承 多态性 C++      更新时间:2023-10-16

我有一个继承自System类的MovementSystem类。稍后我将有许多xxxSystem类,因此我将以这种方式将xxxSystem的实例(每个系统只有一个实例)存储在映射中:

enum
{
    MOVEMENT_SYSTEM
};
std::map<int,std::unique_ptr<System>> systems;
systems[MOVEMENT_SYSTEM] = std::unique_ptr<System>(new MovementSystem());
m_entityManager.loadSystems(&systems);

最后一行在那里,因为我需要我的类EntityManager才能访问所有系统。

因此我有这种方法:

std::map<int,std::unique_ptr<System>> *m_systems; // this line is in the header
void EntityManager::loadSystems(std::map<int,std::unique_ptr<System>> *systems)
{
    m_systems = systems;
}

最后,在另一种EntityManager方法中,我尝试以这种方式访问我发送给班级的系统:

std::unique_ptr<MovementSystem> mvt = (*m_systems)[MOVEMENT_SYSTEM];
mvt->update(dt);

但是我收到此错误:

conversion from 'std::map<int, std::unique_ptr<System> >::mapped_type {aka std::unique_ptr<System>}' to non-scalar type 'std::unique_ptr<MovementSystem>' requested

如何解决此问题并获取最后一行以从MovementSystem调用更新方法?

std::unique_ptr<MovementSystem> mvt = *m_systems[MOVEMENT_SYSTEM];

这条线有两个问题。首先,运算符优先级是这样的,它将被解释为:

*(m_systems[MOVEMENT_SYSTEM])

这意味着它将指针算法应用于指针m_systems(访问m_systems指向的"数组"中的第 MOVEMENT-SYSTEM 个元素),然后将*应用于该映射,这是无稽之谈。你想要的是这个:

(*m_systems)[MOVEMENT_SYSTEM]

第二个问题是你试图复制一个唯一的指针。这正是独特指针旨在防止的。

您可能想要的只是获取指针,并相应地投射它:

MovementSystem *mvt = static_cast<MovementSystem*>((*m_systems)[MOVEMENT_SYSTEM].get());

或者,更好的是因为它摆脱了不必要的指针:

auto &systems = *m_systems;
auto &mvt = static_cast<MovementSystem&>(*systems[MOVEMENT_SYSTEM]);
mvt.update(dt);