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.
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
}