Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Композиция с кратностью многие-ко-многимСодержание книги
Поиск на нашем сайте
Отношение между объектами Book и Author более сложное, чем кажется на первый взгляд. С одной стороны, авторами одной и той же книги может быть несколько человек. С другой стороны - один автор мог участвовать в написании нескольких разных книг. Отношение с такой кратностью называют композицией многие-ко-многим. Это наиболее сложный вид композиции из всех возможных.
Отношение многие-ко-многим в большинстве случаев должно быть реализовано без ответственности за уничтожение. Такое отношение образует сложный граф связей между объектами, и понять используется объект где-либо еще достаточно сложно. Часто отношение многие-ко-многим представляет в предметной области некоторое логическое объединение нескольких сущностей в группу, нежели более сильное отношение владения, предполагающее ответственность за уничтожение. Обычно объекты, связанные отношением многие-ко-многим, создает и уничтожает какой-то третий объект, ответственный за хранение всех участвующих в такой модели объектов. В примере о книгах и авторах такую роль мог бы играть класс Library (библиотека).
Важной особенностью реализации такого вида композиции является обязательность использования форвардных деклараций в заголовочных файлах. Допустим, это ограничение нарушено, и программист использует директивы #include, чтобы связать определения классов друг с другом:
book.hpp
#include “author.hpp”
class Book { //... };
author.hpp
#include “book.hpp”
class Author { //... };
Попытка сборки проекта с таким подходом неизбежно приведет к зависанию либо фатальному сбою компилятора. Обрабатывая цепочку директив #include, препроцессор не сможет выбраться из бесконечной рекурсии, поскольку файлы включают друг друга.
Использование форвардных деклараций позволяет разорвать этот замкнутый круг. Директивы #include, свою очередь, размещают не в заголовочных файлах, а в файлах реализации классов. При этом, заголовочные файлы не могут использовать полные определения классов своих дочерних объектов. Соответственно, объявления всех полей и методов, как максимум, могут использовать эти классы только в виде указателя или ссылки, не обращаясь к содержимому. Работа с содержимым, при этом, в свободном доступе в CPP-файлов классов, поскольку они компилируются отдельно друг от друга и не образуют бесконечную рекурсию при компиляции.
Ниже представлен набросок примера с композицией многие-ко-многим, а полную версию можно посмотреть по ссылке в конце лекции.
author.hpp
#ifndef _AUTHOR_HPP_ #define _AUTHOR_HPP_
/*****************************************************************************/
#include <unordered_set> #include <memory> #include <functional> #include <string>
/*****************************************************************************/
// Форвардное объявление class Book;
/*****************************************************************************/
class Author {
/*-----------------------------------------------------------------*/
public:
/*-----------------------------------------------------------------*/
// …
// Метод, возвращающий количество книг автора int getBooksCount () const;
// Метод, выясняющий участвовал ли автор в написании указанной книги bool hasBook (Book const & _book) const;
// Метод, регистрирующий очередную книгу автора void addBook (Book const & _book);
// Метод, отменяющий регистрацию одной из книг автора void removeBook (Book const & _book);
// Метод очистки набора книг void clearBooks ();
// Метод обхода набора книг с применением указанного пользовательского действия void forEachBook (std::function< void (Book const &) > _action) const;
/*-----------------------------------------------------------------*/
private:
/*-----------------------------------------------------------------*/
// …
// Множество книг автора std::unordered_set< Book const * > m_books;
/*-----------------------------------------------------------------*/
};
/*****************************************************************************/
#endif // _AUTHOR_HPP_
author.cpp
#include “author.hpp” #include “book.hpp”
// Реализация методов автора...
library.hpp
#ifndef _LIBRARY_HPP_ #define _LIBRARY_HPP_
/*****************************************************************************/
#include <vector> #include <memory>
/*****************************************************************************/
// Форвардные объявления class Book; class Author;
/*****************************************************************************/
class Library {
/*-----------------------------------------------------------------*/
public:
/*-----------------------------------------------------------------*/
void addBook (std::unique_ptr< Book > _book);
//... другие полезные методы для работы с книгами
/*-----------------------------------------------------------------*/
void addAuthor (std::unique_ptr< Author > _authors);
//... другие полезные методы для работы с авторами
/*-----------------------------------------------------------------*/
private:
/*-----------------------------------------------------------------*/
// Книги библиотеки std::vector< std::unique_ptr< Book > > m_books;
// Авторы книг библиотеки std::vector< std::unique_ptr< Author > > m_authors;
/*-----------------------------------------------------------------*/
};
/*****************************************************************************/
#endif // _LIBRARY_HPP_
library.сpp
#include “library.hpp” #include “author.hpp” #include “book.hpp”
// Реализация методов библиотеки…
Полные примеры из лекции
https://github.com/zaychenko-sergei/oop-samples/tree/master/lec10
Выводы
В данной лекции были показаны типичные ошибки начинающих программистов при реализации отношения композиции между объектами на основе STL-контейнеров, а также выданы подробные рекомендации по удачному стилю реализации родительских классов. Рассматривались возможные варианты улучшения инкапсуляции при помощи контейнерных итераторов, а также средства std::function.
Позднее было введено понятие умных указателей, в частности, std::unique_ptr, и рассматривались способы их применения для упрощения реализации одиночной и множественной композиции с ответственностью за уничтожение дочерних объектов.
В завершении речь шла о вариантах оптимизации быстродействия композиции объектов за счет использования стандартных реализаций отображений и множеств, а также особенности применения композиции с кратностью многие-ко-многим, в частности, обязательность форвардных деклараций для разрыва компиляционных зависимостей.
|
||
|
Последнее изменение этой страницы: 2017-02-17; просмотров: 179; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.198 (0.008 с.) |