How to automatically maintain a list of class inst

2019-05-28 11:25发布

问题:

In my C++ project, I have an Engine class and an Object class.

My issue lies with how my instances of Object are created. Currently this is done through the use of a CreateObject(parameters) function in the Engine class. This adds a new instance of Object to an std::vector of Object instances.

I want to maintain this list of instances of Object in my Engine class, but without the need for the CreateObject(parameters) function. My reason for this is so that I can create new classes that can inherit from Object but still be added to this list. The reason for this list is so that (in Engine) I can iterate through every Object instance that has been created.

This would ultimately mean that I create my Object instances with something like Object newObject = Object(parameters);, but still have the Engine class maintain a list of all Object instances, without the need for Object to reference the instance of Engine or the list to add itself to this list (as in the instance of Object should not know about the list it is in). Can this be done?

回答1:

You can define a static collection data member in your Engine class, update it in your Object constructor and destructor:

class Engine
{
    friend class Object;
...
public:
    static std::set< Object* > m_instances;
};

class Object
{
public:
    Object();
    virtual ~Object();
    ...
};

You increment it in constructors, and decrement it in destructors.

Object::Object()
{
    Engine::m_instances.insert(this);
}

Object::~Object()
{
    Engine::m_instances.erase(this);
}


回答2:

I think your factory pattern approach is the good way to achieve this. The engine manages all the instances of Objects internally.

But if you want to make external instances, managed by the engine too, you must have to access a instance of the engine; even if that instance is a global variable, even if the Engine class implements a singleton pattern.

The second best approach to do that (The first is what yoa are doint yet, the factory), I think is to implement a singleton in the Engine:

class Object
{
    Object
    {
        Engine::instance().addObject( this ); //Note that engine stores pointers. STL containers cannot store references.
    }

    ~Object
    {
       Engine::instance().releaseObject( this );
    }
};


回答3:

Use a static

    vector<Object*> Objects

variable in Engine class and static public function

    Push(Object* obj) { Objects.push_back(obj); }

to push Objects to the list. Then in constructor of your Object class you would call

    Engine::Push(this)


回答4:

Like many have mentioned, factory architecture is a nice and clean way to go, otherwise you are going to have to have a global instance, static members or a singleton. However, a static approach would be to make Object a friend of class engine and make the members static:

class Engine{
     friend class Object;

     private:
     static std::vector <Object*> objectList;
};

This will allow Object to access private members of Engine statically. Then in the constructor of Object, add it to the list like so:

Object::Object(int randomparam1, const char* randomparam2)
{
    Engine::objectList.push_back(this);
}