Композиция объектов с кратностью многие-ко-многим. Основные особенности объектных отношений, способы реализации
Отношение многие-ко-многим в большинстве случаев должно моделироваться без ответственности за уничтожение. Такое отношение образует сложные связи между объектами, и понять используется объект где-либо еще достаточно сложно. Часто отношение многие-ко-многим представляет в предметной области некоторое логическое объединение нескольких сущностей в группу, нежели более сильное отношение владения.
Обычно объекты, связанные отношением многие-ко-многим, создает и уничтожает какой-то третий объект, ответственный за хранение всех участвующих в такой модели объектов.
Наследование классов. Необходимость в отношении наследования. Структура наследования в памяти. Повышающее преобразование типа.
Наследование — механизм языка, позволяющий описать новый класс на основе уже существующего (родительского, базового) класса. Класс-потомок может добавить собственные методы и свойства, а также пользоваться родительскими методами и свойствами. Позволяет строить иерархии классов. Является одним из пяти типов ассоциации.
Механизм наследования – механизм языка, который позволяет создавать новые классы расширяя возможности существующих, при этом имея возможность использовать объекты новых классов везде, где можно использовать оригинальные объекты. В отличие от композиции, создающей иерархии объектов по принципу целое-часть, при помощи наследования формируют иерархии классов с отношениями общее-частное. Наследование предполагает, что новый класс, называемый подклассом (subclass) либо классом-потомком, классом-наследником (derived class), объявляет некоторый существующий класс своим базовым (base class) или суперклассом (superclass). В результате, класс-потомок получает все члены родительского класса, может дополнять их новыми, а объекты класса-потомка могут преобразовываться к объектам базового класса.
Интересно, что на низком уровне с точки зрения структуры объектов в памяти обе версии классов Bus и Truck - до внедрения отношения наследования и после - будут выглядеть идентично - в начале объектов производных классов будут размещаться члены базового класса, а новые дополнительные члены будут находиться после них:
Вся разница, вносимая наследованием, состоит в возможности автоматического преобразования типа от класса-потомка к базовому классу. Такое преобразования типа называется ПОВЫШАЮЩИМ (upcast, движемся вверх по иерархии). Также упрощается доступ к членам базового класса. Вместо прежнего обращения через базовый объект:
std::cout << b.getVehicle().getWeight()
<< b.getVehicle().getEngine().getHorsePower();
можно воспользоваться методом базового класса напрямую:
std::cout << b.getWeight() << b.getEngine().getHorsePower();
Не следует путать преобразование типа к базовому классу для ссылок/указателей с аналогичными действиями для значений.