Как я могу получить доступ к функции интерфейса дочернего объекта, хранящегося в векторе указателей его базового класса? ⇐ C++
Как я могу получить доступ к функции интерфейса дочернего объекта, хранящегося в векторе указателей его базового класса?
Чего я пытаюсь достичь: Я хочу иметь возможность перебирать вектор базовых классов и ссылаться на интерфейс дочернего класса.
Где я сейчас: Я работаю над созданием системы для игры, в которой у вас есть игровые объекты, и вы можете добавить функциональность к игровому объекту, добавив компонент.
Я создал класс GameObject со списком компонентов. Этот класс проходит через все компоненты и вызывает три функции компонента: handleInput(), update() и draw().< /п> GameObject.h
#include "IInitialize.h" #include "IInput.h" #include "IUpdate.h" #include "IDraw.h" #include "TransformComponent.h" класс Компонент; класс GameObject: public IInitialize, IInput, IUpdate, IDraw { публика: Преобразование TransformComponent; ИгровойОбъект(); void addComponent (компонент * компонент); bool IInitialize::initialize() { вернуть истину; } void IInput::handleInput(окно sf::RenderWindow*, событие sf::Event*) { for (auto it =Components.begin(); it!=Components.end(); it++) { Компонент IInput* = Dynamic_cast(*it); если (компонент!= nullptr) { компонент->handleInput(окно, событие); } } } void IUpdate::update(float deltaTime) { for (auto it =Components.begin(); it!=Components.end(); it++) { Компонент IUpdate* = Dynamic_cast(*it); если (компонент!= nullptr) { компонент.обновление(дельтаВремя); } } } void IDraw::draw(окно sf::RenderWindow*) { for (auto it =Components.begin(); it!=Components.end(); it++) { Компонент IDraw* = Dynamic_cast(*it); если (компонент!= nullptr) { компонент.draw(окно); } } } частный: компоненты std::vector; }; GameObject.cpp
#include "GameObject.h" GameObject::GameObject() { Трансформация = ТрансформацияКомпонент(); Transform.position = sf::Vector2f(960, 540); } void GameObject::addComponent(компонент* компонент) { компонент->родитель = это; компоненты.push_back(std::move(компонент)); } В функциях handleInput(), update() и draw() я пытаюсь получить интерфейсы от вызываемого компонента их.
Базовый класс компонентов не реализует интерфейсы, но это реализуют дочерние классы базовых классов компонентов.
Component.h
#include "IInitialize.h" класс GameObject; Компонент класса: public IInitialize { публика: родительский объект GameObject*; Компонент(); виртуальный bool IInitialize::initialize() { вернуть истину; } }; TextComponent.h
#include "Component.h" #include "IUpdate.h" #include "IDraw.h" класс TextComponent: общедоступный компонент, IUpdate, IDraw { публика: std::string text = "Текст"; sf::Color color = sf::Color::Белый; размер int = 25; TextComponent(std::string text = "Text", sf::Color color = sf::Color::White, размер int = 25); недействительный setPosition(); bool IInitialize::initialize() переопределить { если (!_font.loadFromFile(_fontPath)) { вернуть ложь; } вернуть истину; } void IUpdate::update(float deltaTime) { _text.setString(текст); _text.setFillColor(цвет); _text.setCharacterSize(размер); УстановитьOrigin(); установитьТекстПозицию(); } void IDraw::draw(окно sf::RenderWindow*) { окно->рисовать(_текст); } частный: сф::Шрифт _font; sf::Текст _text; std::string _fontPath = "Активы/Шрифты/accidental_presidency.ttf"; недействительный setOrigin(); }; Моя проблема: Моя проблема заключается в том, что объекты, которые я храню в векторе компонентов, являются дочерними классами, производными от класса Component. Я думаю, что нарезка объектов происходит потому, что класс базового компонента не реализует ни один из интерфейсов, и когда GameObject пытается привести класс Component к IInput, IUpdate или IDraw не удается, поскольку базовый класс не реализует эти интерфейсы.
Что я пробовал:
[*]
Я рассматривал возможность приведения компонента к правильному типу, чтобы получить интерфейс, но для этого игровому объекту потребуется знать о различных типах компонентов, а я не уверен, что ему нужно это знать. о них. Мне также потребуется обновлять класс GameObject каждый раз, когда я создаю новый компонент.
[*]
Я пытался создать класс посредника, который всегда будет наследоваться от интерфейсов. Это ограничивает использование интерфейсов и приводит к тому, что иногда функция остается неиспользованной, потому что компоненту не нужно ее использовать.
[*]
Я добавил интерфейсы в базовый класс и переопределил их в дочерних классах. Это также приводит к тому, что иногда некоторые функции интерфейса остаются неиспользованными. Моей целью было добавить интерфейс только к тем объектам, которые его используют.
Мой вопрос: Как я могу спроектировать архитектуру, чтобы я мог использовать интерфейсы своих дочерних объектов без необходимости предоставлять GameObject слишком много информации о типах компонентов?
Чего я пытаюсь достичь: Я хочу иметь возможность перебирать вектор базовых классов и ссылаться на интерфейс дочернего класса.
Где я сейчас: Я работаю над созданием системы для игры, в которой у вас есть игровые объекты, и вы можете добавить функциональность к игровому объекту, добавив компонент.
Я создал класс GameObject со списком компонентов. Этот класс проходит через все компоненты и вызывает три функции компонента: handleInput(), update() и draw().< /п> GameObject.h
#include "IInitialize.h" #include "IInput.h" #include "IUpdate.h" #include "IDraw.h" #include "TransformComponent.h" класс Компонент; класс GameObject: public IInitialize, IInput, IUpdate, IDraw { публика: Преобразование TransformComponent; ИгровойОбъект(); void addComponent (компонент * компонент); bool IInitialize::initialize() { вернуть истину; } void IInput::handleInput(окно sf::RenderWindow*, событие sf::Event*) { for (auto it =Components.begin(); it!=Components.end(); it++) { Компонент IInput* = Dynamic_cast(*it); если (компонент!= nullptr) { компонент->handleInput(окно, событие); } } } void IUpdate::update(float deltaTime) { for (auto it =Components.begin(); it!=Components.end(); it++) { Компонент IUpdate* = Dynamic_cast(*it); если (компонент!= nullptr) { компонент.обновление(дельтаВремя); } } } void IDraw::draw(окно sf::RenderWindow*) { for (auto it =Components.begin(); it!=Components.end(); it++) { Компонент IDraw* = Dynamic_cast(*it); если (компонент!= nullptr) { компонент.draw(окно); } } } частный: компоненты std::vector; }; GameObject.cpp
#include "GameObject.h" GameObject::GameObject() { Трансформация = ТрансформацияКомпонент(); Transform.position = sf::Vector2f(960, 540); } void GameObject::addComponent(компонент* компонент) { компонент->родитель = это; компоненты.push_back(std::move(компонент)); } В функциях handleInput(), update() и draw() я пытаюсь получить интерфейсы от вызываемого компонента их.
Базовый класс компонентов не реализует интерфейсы, но это реализуют дочерние классы базовых классов компонентов.
Component.h
#include "IInitialize.h" класс GameObject; Компонент класса: public IInitialize { публика: родительский объект GameObject*; Компонент(); виртуальный bool IInitialize::initialize() { вернуть истину; } }; TextComponent.h
#include "Component.h" #include "IUpdate.h" #include "IDraw.h" класс TextComponent: общедоступный компонент, IUpdate, IDraw { публика: std::string text = "Текст"; sf::Color color = sf::Color::Белый; размер int = 25; TextComponent(std::string text = "Text", sf::Color color = sf::Color::White, размер int = 25); недействительный setPosition(); bool IInitialize::initialize() переопределить { если (!_font.loadFromFile(_fontPath)) { вернуть ложь; } вернуть истину; } void IUpdate::update(float deltaTime) { _text.setString(текст); _text.setFillColor(цвет); _text.setCharacterSize(размер); УстановитьOrigin(); установитьТекстПозицию(); } void IDraw::draw(окно sf::RenderWindow*) { окно->рисовать(_текст); } частный: сф::Шрифт _font; sf::Текст _text; std::string _fontPath = "Активы/Шрифты/accidental_presidency.ttf"; недействительный setOrigin(); }; Моя проблема: Моя проблема заключается в том, что объекты, которые я храню в векторе компонентов, являются дочерними классами, производными от класса Component. Я думаю, что нарезка объектов происходит потому, что класс базового компонента не реализует ни один из интерфейсов, и когда GameObject пытается привести класс Component к IInput, IUpdate или IDraw не удается, поскольку базовый класс не реализует эти интерфейсы.
Что я пробовал:
[*]
Я рассматривал возможность приведения компонента к правильному типу, чтобы получить интерфейс, но для этого игровому объекту потребуется знать о различных типах компонентов, а я не уверен, что ему нужно это знать. о них. Мне также потребуется обновлять класс GameObject каждый раз, когда я создаю новый компонент.
[*]
Я пытался создать класс посредника, который всегда будет наследоваться от интерфейсов. Это ограничивает использование интерфейсов и приводит к тому, что иногда функция остается неиспользованной, потому что компоненту не нужно ее использовать.
[*]
Я добавил интерфейсы в базовый класс и переопределил их в дочерних классах. Это также приводит к тому, что иногда некоторые функции интерфейса остаются неиспользованными. Моей целью было добавить интерфейс только к тем объектам, которые его используют.
Мой вопрос: Как я могу спроектировать архитектуру, чтобы я мог использовать интерфейсы своих дочерних объектов без необходимости предоставлять GameObject слишком много информации о типах компонентов?
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение