В классе Entity есть функция, которая принимает имя типа компонента в качестве аргумента и должна возвращать указатель на этот компонент, если он найден в массиве компонентов. Вместо этого он просто возвращает копию компонента, а не указатель, несмотря на это:
return static_cast<T*>(ptr)
Вот соответствующий код:
ECS.h (только необходимый код).
inline ComponentTypeId getUniqueComponentID() {
static ComponentTypeId lastID = 0u;
return lastID++;
}
template <typename T> inline ComponentTypeId getComponentTypeID() noexcept {
static_assert(std::is_base_of<Component, T>::value, "Failed at getComponentTypeID/static_assert() --> ECS/ECS.h");
static const ComponentTypeId typeID = getUniqueComponentID();
return typeID;
}
// Base "Component" class
class Component {
// Code
};
// Base "Entity" class
class Entity {
private:
ComponentArray compArr;
ComponentBitset compBitset;
std::vector<std::unique_ptr<Component>> components;
bool active = true;
public:
Entity() {}
virtual ~Entity() {}
template<typename T> bool hasComponent() const {
// Returns the bitset (bool value)
return compBitset[getComponentTypeID<T>()];
}
template<typename T> T& getComponent() const {
// Returns pointer to component
return *static_cast<T*>(compArr[getComponentTypeID<T>()]);
}
void update() {
// Goes through all the components (for this entity) calls their update method
for(auto &c : components) c->update();
}
void draw() {
// Goes through all the components (for this entity) calls their draw method
for(auto &c : components) c->draw();
}
inline bool isActive() {return active;}
void destroy() {active = false;}
};
Ваша функция возвращает ссылку, а не указатель. Однако он не делает копию. Пожалуйста, покажите, как вы на самом деле используете функцию и в чем проблема. Также сократите свой код до минимального воспроизводимого примера. Показанное использование не работает, потому что ваша функция возвращает не указатель, а ссылку. static_cast<T*>(ptr)
— это указатель, добавление *
приведет к разыменованию указателя.
@AviBerger Функция возвращает по ссылке. В показанном коде нет очевидного места, где можно было бы сделать копию.
@ user17732522, правда. Я не прочитал первые несколько строк сообщения до точки, где был полный код функции.
даже изменение *static_cast<T*>(ptr)
на static_cast<T*>(ptr)
не устраняет ошибку компиляции. Вот ошибка: `В файле, включенном из ./src/ECS/components.h:11:0, из ./src/game.cpp:7: ./src/ECS/hitbox_component.h: в функции-члене 'virtual void HitboxComponent::init()': ./src/ECS/hitbox_component.h:25:23: ошибка: невозможно преобразовать 'TransformComponent' в 'TransformComponent*' в назначении transform = parent->getComponent<TransformComponent>(); Makefile:2: рецепт для целевой сборки не удалось сделать: *** [сборка] Ошибка 1 `
Код не делает то, что говорит комментарий. Тип возвращаемого значения — это ссылка на T, а не указатель на T. Кажется, кто-то изменил код, не изменив комментарий.
@КешавВ. Вы также изменили тип возвращаемого значения со ссылки на указатель?
Если вы хотите вернуть указатель, вам не нужна ведущая звездочка. Вы бы включили эту звездочку, чтобы вернуть ссылку. Если объект и время его жизни корректны, можно использовать любой подход.
Оказывается, я возвращал ссылку вместо указателя в функции getComponent().
template<typename T> T& getComponent() const {
// Returns pointer to component
return *static_cast<T*>(compArr[getComponentTypeID<T>()]);
}
// Needs to be
template<typename T> T* getComponent() const {
// Returns pointer to component
return static_cast<T*>(compArr[getComponentTypeID<T>()]);
}
* Я забыл поставить точку с запятой в строке 4 для примера, но это не меняет проблемы, поскольку она присутствует в коде.