Форум программистов, компьютерный форум CyberForum.ru

Альтернатива виртуальным функциям в конструкторе - C++

Восстановить пароль Регистрация
 
ZiminAS1990
 Аватар для ZiminAS1990
2 / 2 / 0
Регистрация: 27.07.2012
Сообщений: 31
07.05.2013, 23:12     Альтернатива виртуальным функциям в конструкторе #1
Доброе время суток, коллеги!

В процессе разработки одной библиотечки столкнулся с такой проблемой:

Допустим есть базовый класс Popcorn. Когда я создаю Popcorn, он "приготавливается" прямо в своём конструкторе: засыпается кукуруза, включается печь, добавляется некоторый ингредиент и т.д.
Я хочу предложить своим довольным покупателям аж три разных попкорна: простой, солёный и сладкий. Разница лишь в ингредиенте, добавляемым в процессе приготовления.
Как это можно представить с точки зрения ООП:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Popcorn {
public:
  Popcorn() {
    // Начинаем приготовление...
    // Добавляем ингредиент:
    addIngredient(getIngredient());
    // Завершаем приготовление...
  }
 
protected:
  // Получить ингредиент, который будет добавлен:
  virtual Ingredient getIngredient() {
    // В простом попкорне ничего не добавляем
    return noIngredient;
  }
 
private:
  // Добавить ингредиент к попкорну
  void addIngredient(Ingredient ingredient);
 
};
Как видите, "изюминка" класса - виртуальная функция getIngredient, которая возвращает ингредиент, который должен быть добавлен в процессе приготовления.
Теперь я хочу сделать сладкий и солёный попкорн. Поэтому я делаю так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class SweetPopcorn : public Popcorn {
  ...
protected:
  virtual Ingredient getIngredient() {
    // В сладком попкорне добавляем сахар
    return Sugar;
  }
 
};
 
 
class SaltPopcorn : public Popcorn {
  ...
protected:
  virtual Ingredient getIngredient() {
    // В солёном попкорне добавляем соль
    return Salt;
  }
 
};
Естественно, это работать не будет, так как при приготовлении как сладкого, так и солёного попкорна, функция getIngredient вернёт нам ничего (noIngredient) и две трети моих покупателей больше ко мне не вернуться
Как это обойти?

Повторюсь, что пример вырожденный. Можно было конечно всё сделать иначе....
Например ингредиент можно было добавить в конструктор Popcorn и вообще ничего не наследовать. Но тогда покупатели вместо "Будьте добры простой попкорн" вынуждены будут говорить "Будьте добры попкорн с добавлением ничего".
Можно было процесс приготовления вынести из конструктора в функцию "Cook" и вызывать её после создания объекта, но это всё равно, что сказать: "Вот Ваш попкорн, вон там в углу стоит микроволновка. Положите пакет в микровоновку на три минуты и получите свой попкорн. Спасибо за покупку!".
Можно было бы создать три разных класса без наследования, и в конструкторах прописать процесс приготовления с добавлением нужного ингредиента. Но это всё равно что поставить рядом три лавки и три продавца, которые будут продавать три разных попкорна.

Короче, как бы сделать так, что если я создаю объект SweetPopcorn, то я получаю своё сладкий попкорн без дополнительных телодвижений и параметров в конструкторах?

Заранее благодарю за ответы
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
07.05.2013, 23:36     Альтернатива виртуальным функциям в конструкторе #2
ZiminAS1990, а в конструкторы классов наследников вынести это?
C++
1
2
3
4
5
6
7
class SweetPopcorn : public Popcorn {
   // ...
   SweetPopcorn() {
      addIndigrient(getIndigrient());
   }
   // ...
};
Конечно придётся всё это ручками писать, но с другой стороны: как узнать то, что ещё не создано?
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
08.05.2013, 11:15     Альтернатива виртуальным функциям в конструкторе #3
Цитата Сообщение от gray_fox Посмотреть сообщение
а в конструкторы классов наследников вынести это?
Главное, чтобы потом никто не придумал SweetChickenPopcorn : public SweetPopcorn.
Т.е. если класс конечный в иерархии, то можно и в конструкторе виртуальную функцию вызвать.
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
08.05.2013, 11:22     Альтернатива виртуальным функциям в конструкторе #4
Цитата Сообщение от ZiminAS1990 Посмотреть сообщение
Короче, как бы сделать так, что если я создаю объект SweetPopcorn, то я получаю своё сладкий попкорн без дополнительных телодвижений и параметров в конструкторах?
покупатели покупают попкорн у продавца, вот и создай его, он же пусть и готовит попкорн
programina
08.05.2013, 11:38
  #5

Не по теме:

вот из-за таких горе-программистов возникает безработица

ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
08.05.2013, 11:46     Альтернатива виртуальным функциям в конструкторе #6
ZiminAS1990, Да не сможешь ты сделать так. Ты все правила нарушил. Короче в базовом классе в конструкторе инициируй основные ингредиенты общие для все производных классов, а в производных классах уже храни дополнительные ингредиенты и у тебя получится при создании объекта производного класса ты с инициируешь дополнительные ингредиенты (допустим сахар) и основные которые входят в базовый класс. Можешь по умолчанию задать им какие нибудь значения и тебе не нужно будет делать дополнительные движения.
-=ЮрА=-
Заблокирован
Автор FAQ
08.05.2013, 11:48     Альтернатива виртуальным функциям в конструкторе #7

Не по теме:

Сделать один класс PopCorn со свойством Property - дефалтом путь идёт сладкий, а дальше меняем Property на нужный - солёный там, с карамелью, с вишней и т.д. Зачем полодить классы наследники вообще?



Добавлено через 1 минуту

Не по теме:

ZiminAS1990, напиши своё задание, что тебе 100% надо использовать, там классы, перегрузки, наследование, что из этого нужно и что нет..?А уж народу тут найдётся много подсказать более удачные решения

ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
08.05.2013, 12:00     Альтернатива виртуальным функциям в конструкторе #8
ZiminAS1990, http://en.wikibooks.org/wiki/More_C%...al_Constructor
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.05.2013, 20:52     Альтернатива виртуальным функциям в конструкторе
Еще ссылки по теме:

Задачи по функциям. Объясните задачу по функциям) C++
можно объявлять конкретный класс с чисто виртуальным методом C++
C++ Разница между виртуальным и простым методом

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
08.05.2013, 20:52     Альтернатива виртуальным функциям в конструкторе #9
Цитата Сообщение от ForEveR Посмотреть сообщение
http://en.wikibooks.org/wiki/More_C%...al_Constructor
более нагляднее тут
Yandex
Объявления
08.05.2013, 20:52     Альтернатива виртуальным функциям в конструкторе
Ответ Создать тему
Опции темы

Текущее время: 09:30. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru