Как создать вектор для хранения адресов всех детей?

Я пытаюсь создать базовый игровой движок на C++, и я хочу, чтобы объект Engine мог перебирать все дочерние элементы GameObject для запуска их методов обновления, для этого я хочу использовать вектор всех дочерних элементов в классе Engine.

Например:

Это похоже на то, что я пытался сделать:

Класс основного двигателя

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

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

    void Update() {
        //Do stuff
    }

}

Цикл основного кода

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

  engine.AddNewObject(object); //Add object

  engine.run();
}

Любая помощь будет принята с благодарностью, спасибо.

GameObject, вероятно, не должен быть ребенком Engine. Это означает, что каждый отдельный объект в вашей игре на самом деле является собственным игровым движком, что менее чем разумно. Кроме этого и некоторого возможного нарезки объектов, если вы планируете создавать подклассы GameObject (что можно исправить старым добрым unique_ptr), я не вижу здесь никаких проблем.
Silvio Mayolo 23.11.2022 02:29

будьте очень осторожны при хранении объектов в контейнерах. это работает, но убедитесь, что вы не создаете копии. Я видел много кода, который имеет несколько копий «одного и того же» объекта, которые обновляются в разных запусках. Лучше поставить смарт птр в векто

pm100 23.11.2022 02:34

У вас есть план. (На самом деле я вижу два плана — один включает «вектор всех дочерних элементов», а другой — вектор адресов всех дочерних элементов.) Так что действуйте. Какой вопрос? Вы столкнулись с проблемой? Каковы симптомы?

JaMiT 23.11.2022 02:39

@SilvioMayolo Спасибо за совет, я попробовал, и количество ошибок сократилось вдвое, а совет Брэда решил проблему.

Parzivil 23.11.2022 03:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Здесь есть несколько проблем. Во-первых, ваш вектор должен быть вектором ссылок или указателей, иначе GameObjects.push_back(obj); создаст копию obj для помещения в вектор (если вы не переместите его) и полиморфизм не будет работать (вы не можете удерживать подклассы GameObject).

То, как вы подходите к этому, зависит от того, какой объект вы хотите владеть памятью, связанной с каждым GameObject. Тривиальное исправление заключается в использовании вектора указателей:

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
            }
        }
    }

Однако с современным C++ вы, вероятно, захотите использовать интеллектуальный указатель, такой как 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
            }
        }
    }

Используя уникальный указатель, вам придется изменить другой код:

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();
}

Наконец, ваша иерархия классов выглядит недействительной. Вероятно, вам не нужно или вы не хотите, чтобы GameObject был подклассом Engine, поскольку они не имеют ничего общего. GameObject, вероятно, сам по себе является хорошим базовым классом, и другие игровые объекты могут его наследовать.

Я последовал вашему совету и удалил GameObject как дочерний элемент Engine, а также исправил свою проблему, связанную с тем, что вектор не стал указателем. Кажется, проблема исправлена.

Parzivil 23.11.2022 03:48

Другие вопросы по теме