C++ |返回对派出的派生类型的shared_ptr的向量的引用

发布于 2025-02-12 12:21:08 字数 2609 浏览 0 评论 0原文

我一直在尝试在C ++中实现自己的实体组件系统,而我对这种编程语言的新手很新,我感到非常满意。 但是,我最近遇到了一个我似乎无法弄清楚的问题。

我已经创建了一个无序的地图,其中我将组件的type_index作为 key vector < /代码> shared_ptr s to该类型的组件as value ;但是,由于我的组件都是不同的结构,因此我使用共享指针将它们存储为其基类(icomponent)。

我现在希望能够通过将我想要的组件的type_index传递给我想要的功能,从而从unordered_map中获取它,从而获取相关组件类型的向量。 。但这是问题:由于我将指针存储为icomponent,因此在从getComponents函数返回时,我无法将其用作正确的类型。因此,我尝试施放每个元素,但是通过这样做,我返回了一个新的vector,该引用未存储在unordered_map中,因此,当我修改此<时,代码>向量在我代码的其他部分中,更改将无法保存。

以下是一些代码片段:

componentManager:

// an unordered map which stores the component types and their vectors
// key: the component's type index
// value: the vector containing the shared pointers of the components of that type_index
std::unordered_map<std::type_index, std::vector<std::shared_ptr<IEComponent>>> components_map;

// create a new component and assign an entity id
template<typename T>
std::shared_ptr<T> CreateComponent(const UUID& e_id) {
    // get the type_index using the type_info from the generic T type
    // (the type_info is returned by the typeid(T) operator)
    std::type_index type_idx = std::type_index(typeid(T));
    // check if the given key exists in the component container
    // if it doesn't exist, create it
    if (components_map.find(type_idx) == components_map.end()) {
        // log the new component type info
        TraceLog(LOG_INFO,
            "COMPONENT_MANAGER: Added new type_idx to the components map. [%s]",
            type_idx.name()
        );
        // save the new type_index to the map with an empty vector as value
        components_map.emplace(type_idx, std::vector<std::shared_ptr<IEComponent>>());
    }
    // create a new T component shared pointer
    std::shared_ptr<T> component = std::make_shared<T>();
    // assign an entity id
    component->e_id = e_id;
    // get the current components_of_type using the type_index
    std::vector<std::shared_ptr<IEComponent>>& components_of_type = GetBaseComponents(type_idx);
    // add the new component to the vector
    components_of_type.push_back(component);
    // return the component
    return component;
}

我想完成的工作:

    for (std::shared_ptr<ECPosition> pos : ComponentManager::GetComponents<ECPosition>()) {
        TraceLog(LOG_INFO, "x is: %f y is: %f", pos->x, pos->y);
    }

I've been trying to implement my own entity component system in C++ and altough I'm quite new to this programming language, I've been quite satisfied.
However, I've recently run in a problem that I can't seem to figure out.

I've created an unordered map, in which I'm storing the type_index of my components as Key, and a vector of shared_ptrs to the components of that type as Value; however, since my components are all different structs, I am storing them using the shared pointer to their base class (IComponent).

I now want to be able to the get the vector of the corrent component type, by passing the type_index of the component I want, to a function which gets it from the unordered_map. But here's the problem: since I've stored the pointers as IComponent, when returning them from the GetComponents function, I cannot use them as the correct type. So I tried casting each element, but by doing this I've returned the reference to a new vector which is NOT stored in the unordered_map, and so when I modify this vector in some other part of my code, the changes will not be saved.

Here are some code snippets:

ComponentManager:

// an unordered map which stores the component types and their vectors
// key: the component's type index
// value: the vector containing the shared pointers of the components of that type_index
std::unordered_map<std::type_index, std::vector<std::shared_ptr<IEComponent>>> components_map;

// create a new component and assign an entity id
template<typename T>
std::shared_ptr<T> CreateComponent(const UUID& e_id) {
    // get the type_index using the type_info from the generic T type
    // (the type_info is returned by the typeid(T) operator)
    std::type_index type_idx = std::type_index(typeid(T));
    // check if the given key exists in the component container
    // if it doesn't exist, create it
    if (components_map.find(type_idx) == components_map.end()) {
        // log the new component type info
        TraceLog(LOG_INFO,
            "COMPONENT_MANAGER: Added new type_idx to the components map. [%s]",
            type_idx.name()
        );
        // save the new type_index to the map with an empty vector as value
        components_map.emplace(type_idx, std::vector<std::shared_ptr<IEComponent>>());
    }
    // create a new T component shared pointer
    std::shared_ptr<T> component = std::make_shared<T>();
    // assign an entity id
    component->e_id = e_id;
    // get the current components_of_type using the type_index
    std::vector<std::shared_ptr<IEComponent>>& components_of_type = GetBaseComponents(type_idx);
    // add the new component to the vector
    components_of_type.push_back(component);
    // return the component
    return component;
}

What I want to accomplish:

    for (std::shared_ptr<ECPosition> pos : ComponentManager::GetComponents<ECPosition>()) {
        TraceLog(LOG_INFO, "x is: %f y is: %f", pos->x, pos->y);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文