Вомозжно, если кто-то из Вас читал книгу Прата "C++ Primer Plus", и отвечал на вопросы в конце главы, сталкивался со следующим примером: For each of the following sets of classes, indicate whether public or private derivation is more appropriate for Column B: A B class Bear class PolarBear class Kitchen class Home class Person class Programmer class Person class HorseAndJockey class Person, class Automobile class Driver Ответы, на этот квиз, из книги, таковые: class Bear, class PolarBear public class Kitchen class Home private class Person class Programmer public class Person class HorseAndJockey private class Person, class Automobile class Driver public for Person, private for Driver Я в принципе то согласен, но вот есть парочка вопросов. Поскольку частное наследование делает все публичные методы (интерфейс) базового класса закрытой областью в классе наследнике (т.е. можно юзать внутри класса, но нельзя вызывать снаружи), возникает парочка вопросов. К примеру, в классах Kitchen и Home, так уж ли подходит здесь частное наследование? Не спорю, отношения между этими двумя классами больше попадает под парадигму отношений has-a, нежели is-a, но все-таки. Что, если я создам, к примеру, экземпляр класса Home и захочу запустить тостер, который находится на кухне? Или посудомоечную машину? Писать для этого новые методы в Home, которые просто будут реализовывать интерфейс кухни (вызывать ее методы)? Как-то не очень удобно. Или, скажем, HorseAndJockey. Все-таки, Жокей, он как ни крути, а должен иметь в своем интерфейсе методы Личности, так или нет? Ну и с последним примером так же. Что, для водителя нельзя вызывать методы Person напрямую? И почему Автомобилем я не могу управлять напрямую вызывая методы Automobile из Driver? Ну как-то так.
Ответ
У вас возникли правильные вопросы - в этом части C++ Primer, к сожалению, пропускает два фундаментальных момента, которые очень важны с практической точки зрения:
Favor composition over inheritance.
Приватное наследование в C++ стоит использовать только для выражения отношения is-implemented-in-terms-of (Effective C++, Issue 42), что на практике встречается достаточно редко.
Насчет примеров - если вы правильно ответили на вопросы [1], [3] и про class Driver : public Person в вопросе [5], то можете считать, что с упражнением вы справились.
Остальные случаи действительно попадают под отношение has-a и их стоит моделировать с помощью композиции - так, кухня является частью дома, водитель может быть частью абстракции "автомобиль" (или наоборот, смотря как подходить к данной ситуации)
HorseAndJockey vs Person - это не самый лучший пример, поскольку автором вводится некоторая сущность Jockey, которая может никак не соответствовать классу Person
Комментариев нет:
Отправить комментарий