Создание нового указателя на чистый виртуальный класс

У меня есть класс следующего дизайна:

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
}

Я не могу найти способ добавления Meal-объект menu так как я не могу создать абстрактный объект. Есть ли способ выполнения вышеуказанного кода?
Я бы предпочел это Meal оставайся абстрактным. Я мог бы передать указатель на существующий Mealобъект, но тогда мой unique_ptr вряд ли уникален.

3

Решение

Решением этой проблемы является конструктор виртуальных копий; что не разрешено в C ++ (это не разрешено, потому что конструктор связан с самим классом, его нельзя делегировать дочерним классам). Вот почему clone лучше всего подходит для этой проблемы.

Вот аналогичный ответ, с самым популярным синтаксисом.

Итак, ваш код должен быть

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

Другие решения

Вы могли бы реализовать getNew виртуальный метод, который возвращает новую копию (производного) объекта и использует его вместо этого.

2

По вопросам рекламы [email protected]