0

Есть класс GameObject

// GameObject.hpp
#pragma once

#include "SFML/Graphics.hpp" #include "vector" #include "Core/Window.hpp" #include "Core/BaseComponents/Component.hpp"

using namespace sf;

namespace sfp::core{ class Component; class Window; class GameObject : public RectangleShape{ public: virtual void addComponent(const sfp::core::Component& component);

    template<class T>
    T* findComponentByType();

protected:
    std::vector<Component*> components;
};

}

// GameObject.cpp
#include "Core/GameObject.hpp"

using namespace sfp::core;

void GameObject::addComponent(const sfp::core::Component& component){
    auto* link = (Component *) &component;
    components.push_back(link);
}

template<class T>
T* GameObject::findComponentByType() {
    for (auto component : components) {
        if (auto found = dynamic_cast<T*>(component)) {
            return found;
        }
    }
    return nullptr;
}

Также есть дочерний от GameObject класс Button

//Button.hpp
#pragma once

#include "Core.hpp" #include "Ui/Components/ButtonComponent.hpp" #include "functional"

namespace sfp::ui{ class Button : public sfp::core::GameObject{ public: explicit Button(const Vector2f& size = Vector2f(0, 0));

    void connect(const std::function&lt;void()&gt;&amp; func);

};

}

//Button.cpp
#include "Ui/Button.hpp"

sfp::ui::Button::Button(const Vector2f &size) : GameObject(size) {
    this->addComponent(*new ButtonComponent);
}

void sfp::ui::Button::connect(const std::function<void()>& func) {
    ButtonComponent* myButtonComponent = findComponentByType<ButtonComponent>();
}

При попытке компиляции вижу следующее:

CMakeFiles/sfml-palm.dir/src/Ui/Button.cpp.o: в функции «sfp::ui::Button::connect(std::function<void ()> const&)»:
/home/navnica/Рабочий стол/sfml-palm/src/Ui/Button.cpp:8: неопределённая ссылка на «sfp::ui::ButtonComponent* sfp::core::GameObject::findComponentByType<sfp::ui::ButtonComponent>()»

Сначала думал что GameObject просто не знает что такое ButtonComponent, и потому и ругается. Напрямую подключил ButtonComponent.hpp в GameObject.cpp, но эффект остался тот-же

TruEnot
  • 11
  • В button.cpp недоступно определение findComponentByType(), вот она и не инстанцируется. – Harry Apr 07 '23 at 04:44
  • @Harry почему оно недоступно? Ведь класс наследуется от GameObject, и должен перенимать все публичные поля? Я не совсем понимаю как это работает просто – TruEnot Apr 07 '23 at 09:53
  • Потому что объявление доступно, так что он компилирует... А тело - нет: оно только в GameObject.cpp есть. А в GameObject.cpp компилятору неизвестно, для чего вы его там инстанцировать собрались... Словом, пока всерьез не разберетесь — пользуйтесь правилом "шаблоны — только в заголовочных файлах" :) – Harry Apr 07 '23 at 10:02

0 Answers0