Simple Object Management System I am attempting to create a fast &amp; robust object management system that allows adding, removing and retrieving objects from a "scene". I am trying to wrap my head around the best way to do this regarding ownership and object lifecycle. Code:

main.cpp:

int main()
{
    r3d::scene main_scene;

    game_object&amp; obj = main_scene.create_object("obj", glm::vec3(0, 0, 0), glm::vec3(-90, 0, -90), glm::vec3(1, 1, 1));

    main_scene.remove_object("obj");

    return 0;
}


scene.hpp:

namespace r3d
{
    class scene
    {
    public:
        scene::scene() { }

        game_object&amp; create_object(std::string name,
                                glm::vec3 position = glm::vec3(0, 0, 0),
                                glm::vec3 euler_angles = glm::vec3(0, 0, 0),
                                glm::vec3 scale = glm::vec3(1, 1, 1));

        void remove_object(std::string);

        game_object&amp; get_object(std::string);

    private:
        std::map&lt;std::string, r3d::game_object&gt; game_objects;
    };
}


scene.cpp:

game_object&amp; scene::create_object(std::string name, glm::vec3 position, glm::vec3 euler_angles, glm::vec3 scale)
{
    game_objects.emplace(name, game_object { name, position, euler_angles, scale });

    return game_objects[name];
}

void scene::remove_object(std::string name)
{
    game_objects.erase(name);
}

game_object&amp; scene::get_object(std::string name)
{
    return game_objects[name];
}


game_object.hpp

namespace r3d
{
    class game_object
    {
    public:
        std::string name;

        game_object() {}

        // constructor
        game_object(std::string name, glm::vec3 position, glm::vec3 euler_angles, glm::vec3 scale) 
            : name(name), 
            position(position), 
            euler_angles(euler_angles), 
            scale(scale) 
        {
            printf("New game_object: %s [address: %p]\n", name.c_str(), this);
        }

        // destructor
        ~game_object()
        {
            printf("Delete game_object: %s [address: %p]\n", name.c_str(), this);
        }

        // copy constructor
        game_object(const game_object&amp; source)
            : name { source.name },
            position { source.position },
            euler_angles { source.euler_angles },
            scale { source.scale }
        {
            printf("Copy game_object: %s [from: %p  to: %p]\n", source.name.c_str(), &amp;source, this);
        }

        // move constructor
        game_object(game_object&amp;&amp; source)
            : name { source.name },
            position { source.position },
            euler_angles { source.euler_angles },
            scale { source.scale }
        {
            printf("Move game_object: %s [from: %p  to: %p]\n", source.name.c_str(), &amp;source, this);
        }

    protected:
        glm::vec3 position;
        glm::vec3 euler_angles;
        glm::vec3 scale;
    };
}
the idea being that any other class can access a game_object by name if given a reference to main_scene, even if it doesn't hold a reference to the actual object


You've stated that one of your primary goals is speed. Based on your description above, you can still achieve object lookup and avoid the performance hit of a string dictionary.

One of the easiest ways to do this is to add a header file to the application that defines an enum of numeric, sequential object IDs. This will allow for much faster lookup, and depending on how you define and load your data, you wouldn't even need a map - simply a fixed array.