Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

unique_ptr can't instantiate class because it's abstract

I have an abstract class(Component)
and this class should be owned by another class(GameObject).
Every GameObject has a vector of components.

Header:

 class Component;
        class GameObject{
        public:
            GameObject();
            virtual ~GameObject();
            void addComponent(std::unique_ptr<Component> component);
            void addComponent(Component* component);
        void removeComponent(std::unique_ptr<Component> component);

        virtual void update();
        std::string getInfo();
        
        //return the first component of type T
        template<typename T>
        T* getComponent(){
            for(auto& component : components){
                if(dynamic_cast<T*>(component.get())){
                    return dynamic_cast<T*>(component.get());
                }
            }
            return nullptr;
        }

        // return the component with the type T
        template<typename T>
        std::vector<T*> getComponents(){
            std::vector<T*> components;
            for(auto component : this->components){
                if(dynamic_cast<T*>(component)){
                    components.push_back(dynamic_cast<T*>(component));
                }
            }
            return components;
        }

        
        std::vector<std::unique_ptr<Component>> components;

    };
class Component
    {
    private:
    public:
        Component() = delete;
        virtual ~Component() = 0;
        virtual std::string getInfo();
        
        
        //the game object this component is attached to
        GameObject* gameObject;
        
    };

source:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

std::string GameObject::getInfo() {
    std::stringstream ss;
    ss << typeid(*this).name();
    for (Uint32 i = 0; i < this->components.size(); i++) {
        ss << typeid(components[i]).name() << " " << this->components[i]->getInfo();
    }
}


void GameObject::addComponent(std::unique_ptr<Component> component) {
    components.push_back(std::move(component));
}
void GameObject::addComponent(Component* component) {
    components.push_back(std::move(std::make_unique<Component>(*component)));
}
void GameObject::removeComponent(std::unique_ptr<Component> component) {
    for (auto it = components.begin(); it != components.end(); it++) {
        if (it->get() == component.get()) {
            components.erase(it);
            return;
        }
    }
}

ERROR: cannot instantiate abstract class. file: memory line 3416

>Solution :

Your issue is here:

void GameObject::addComponent(Component* component) {
    components.push_back(std::move(std::make_unique<Component>(*component)));
}

When you dereference component, as far as the compiler knows you still just have a Component, not the actual instantiation–it can’t call the proper copy constructor.

The solution is to just deleted this member function entirely. You already have a version that takes a std::unique_ptr<Component>, so require the user of GameObject to provide the unique_ptr in all cases.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading