Home > Enterprise >  How to create vector to store addresses of all children?
How to create vector to store addresses of all children?

Time:11-23

I am trying to create a basic game engine in C and I want an Engine object to be able to loop through all the GameObject children to run their update methods, to do this I want to use a vector of all children within the Engine class.

For example:

This is similar to what I have been trying to do:

Parent Engine Class

class Engine {
public:
    Engine() {};

    std::vector<GameObject> GameObjects; //Vector to store all GameObjects

    void AddNewObject(GameObject& obj) {
        GameObjects.push_back(obj); //Add new object to the vector array
    }

    void Run() {
        for (int i = 0; i < GameObjects.size(); i  ) {
            GameObjects[i].Update(); //Run the update method of each GameObject
        }
    }
}

GameObject Child Class

class GameObject : public Engine {
public:
    GameObject() {}

    void Update() {
        //Do stuff
    }

}

Main code loop

int main(void) {
  Engine engine;
  
  GameObject object;

  engine.AddNewObject(object); //Add object

  engine.run();
}

Any help would be greatly appreciated, Thanks.

CodePudding user response:

There are a few issues here. First, your vector needs to be a vector of references or pointers, otherwise GameObjects.push_back(obj); makes a copy of obj to place into the vector (unless you move it) and polymorphism won't work (you can't hold subclasses of GameObject).

How you approach this depends on which object you want to own the memory associated with each GameObject. A trivial fix is is by using a vector of pointers:

class Engine {
    public:
        Engine() {};
    
        std::vector<GameObject*> GameObjects; //Vector to store all GameObjects
    
        void AddNewObject(GameObject& obj) {
            GameObjects.push_back(&obj); //Add new object to the vector array
        }
    
        void Run() {
            for (int i = 0; i < GameObjects.size(); i  ) {
                GameObjects[i]->Update(); //Run the update method of each GameObject
            }
        }
    }

However, with modern, C you would want to probably use a smart pointer like unique_ptr:

class Engine {
    public:
        Engine() {};
    
        std::vector<std::unique_ptr<GameObject>> GameObjects; //Vector to store all GameObjects
    
        void AddNewObject(std::unique_ptr<GameObject> obj) {
            GameObjects.push_back(std::move(obj)); //Add new object to the vector array
        }
    
        void Run() {
            for (int i = 0; i < GameObjects.size(); i  ) {
                GameObjects[i]->Update(); //Run the update method of each GameObject
            }
        }
    }

By using a unique pointer, you would have to change your other code:

int main(void) {
  Engine engine;
  
  std::unique_ptr<GameObject> object = std::make_unique<GameObject>();

  // Transfers memory ownership of `object` into `engine`
  engine.AddNewObject(std::move(object)); //Add object

  engine.run();
}

Lastly, your class hierarchy looks invalid. You probably don't need or want GameObject to be a subclass of Engine since they don't share anything in common. GameObject may likely be a good base class itself and other game objects would inherit it.

  • Related