Возврат статического приведения к указателю не возвращает указатель С++

В классе 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;}
};

* Я забыл поставить точку с запятой в строке 4 для примера, но это не меняет проблемы, поскольку она присутствует в коде.

Keshav V. 21.11.2022 05:59

Ваша функция возвращает ссылку, а не указатель. Однако он не делает копию. Пожалуйста, покажите, как вы на самом деле используете функцию и в чем проблема. Также сократите свой код до минимального воспроизводимого примера. Показанное использование не работает, потому что ваша функция возвращает не указатель, а ссылку. static_cast<T*>(ptr) — это указатель, добавление * приведет к разыменованию указателя.

user17732522 21.11.2022 06:01

@AviBerger Функция возвращает по ссылке. В показанном коде нет очевидного места, где можно было бы сделать копию.

user17732522 21.11.2022 06:02

@ user17732522, правда. Я не прочитал первые несколько строк сообщения до точки, где был полный код функции.

Avi Berger 21.11.2022 06:05

даже изменение *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 `

Keshav V. 21.11.2022 06:08

Код не делает то, что говорит комментарий. Тип возвращаемого значения — это ссылка на T, а не указатель на T. Кажется, кто-то изменил код, не изменив комментарий.

MarshallBS 21.11.2022 06:08

@КешавВ. Вы также изменили тип возвращаемого значения со ссылки на указатель?

user17732522 21.11.2022 06:10

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

Avi Berger 21.11.2022 06:16
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
8
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Оказывается, я возвращал ссылку вместо указателя в функции 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>()]);
}

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