Search code examples
c++abstract-base-class

Creating a new pointer to a pure virtual class


I have a class of the following design:

class Meal {
public:
    virtual void cook() = 0; // pure virtual
}

class Omelette : Meal {
public:
    void cook() {/*do something*/}; // non-virtual
}

class Waffle : Meal {
public:
    void cook() {/*do something*/}; // non-virtual
}

std::vector< std::unique_ptr<Meal> > menu;

void addMeal(const Meal& meal) {
    menu.emplace_back(new Meal(meal)); // cannot allocate an object of abstract type
}

I'm unable to find a way of adding a Meal-derived object to the menu since I cannot create an abstract object. Is there a way of performing the above code? I'd prefer that Meal remain abstract. I could pass in a pointer to an existing Meal-derived object, but then my unique_ptr is hardly unique.


Solution

  • The solution to this problem is the virtual copy constructor; which is not allowed in C++ (It is not allowed because constructor is something related to the class itself, it can't be delegated to class's children). That why clone is the best fit for this problem.

    Here is a similar answer, with most popular syntax.

    So, you code shall be

    class Meal {
    public:
        virtual void cook() = 0; // pure virtual
        virtual Meal* clone() const = 0; // pure virtual clone.
    };
    
    class Omelette : public Meal {
    public:
        void cook() {
        /*do something*/ 
        }; // non-virtual
        virtual Omelette* clone() const
        {
            return new Omelette(*this);
        }
    };
    
    class Waffle : public Meal {
    public:
        void cook() {
            /*do something*/
        }; // non-virtual
        virtual Waffle* clone() const
        {
            return new Waffle(*this);
        }
    };
    
    std::vector< std::unique_ptr<Meal> > menu;
    
    void addMeal(const Meal& meal) {
        menu.emplace_back( meal.clone() ); // cannot allocate an object of abstract type
    }