Пусть один класс начинает брать на себя слишком много обязанностей.
class ArtLebedev : public DesignStudio, public BookPublisher {
int money;
Fun fun;
};
Где как, а в ОО рецепт на все один: новый класс. Постараемся, однако, не делать резких движений и на первое время сохранить близкий контакт с отпочковавшимся классом. Оформим его как
(
Read more... )
=) Да, но у этого слова ещё дохрена различных значений.
> насколько я привык, программа, где все кастуется во все, из приятного волшебства быстро превращается в кошмар
Согласен. Но тут это, ИМХО, оправдано, т.к. выполняется отношения ArtLebedev IS DesignStudio и ArtLebedev IS BookPublisher.
> собственно, этот пост и был про то, как начать разделять два класса, но в C++.
Да, просто в вашем решении классы получаются неравноправными.
> я не знаю, подразумевали ли вы максимальную скорость работы.
> если нет, то от static_cast'ов чрезвычайно легко избавиться, сделав чисто виртуальные методы вроде
Да, подразумевал, ведь и нежелание хранить указатель в publisher-е - это тоже оптимизация.
Использование виртуальных функций, кстати, решает ещё одну серьёзную проблему:
вдруг кто-то в конструкторе/деструкторе ArtLebedevDesign обратится к функции publisher и получит обращение к несоздавшемуся/удалённому классу (в вашем случае такое тоже может быть, ведь констуктор publisher вызывается до конструтора "главного класса"). В случае же виртуальных функций будет просто pure virtual function call.
> Плюс, наследование можно сделать приватным, что тоже очень хорошо.
А вот приватное наследование зачем? Казалось бы в "умных книжках" пишут, что приватное наследование надо использовать только в тех случаях, когда публичное что-нибудь нарушает (вроде LSP), а агрегацией не отделаться (надо виртуальные функции какие-нибудь перегружать и пр.). Тут, ИМХО. ничего не нарушается.
Reply
Согласен. Но тут это, ИМХО, оправдано, т.к. выполняется отношения ArtLebedev IS DesignStudio и ArtLebedev IS BookPublisher.
Это нам с вами надо определиться в чем цель измениний. Я подразумеваю, что идет процесс выделения функциональности в отдельный класс. Поэтому интерфейс тоже меняется. Собственно, может быть ради интерфейса это все и затевалось. Речь идет ведь как раз о ссылке на родительский класс, т.е. родительский класс по-прежнему выполняет часть работы.
Reply
Угу, в случае, если эти IS-отношения не выполняются, то агрегация - это самый правильный выбор.
Reply
я, кстати, для себя решил эту проблему решил разделением всего на 2 случая:
либо сложный нетривиальный, либо наследование.
А вот приватное наследование зачем? Казалось бы в "умных книжках" пишут, что приватное наследование надо использовать только в тех случаях, когда публичное что-нибудь нарушает (вроде LSP), а агрегацией не отделаться (надо виртуальные функции какие-нибудь перегружать и пр.). Тут, ИМХО. ничего не нарушается.
Ну так о том и речь. Я не хочу, чтобы снаружи было видно это наследование, а использую его только для получения компактной структуры в памяти. Агрегацию мы отмели в начале разговора.
Reply
Leave a comment