- •1. Абстракция и декомпозиция. Основные виды декомпозиции программ.
- •Модульная декомпозиция
- •В заголовочный файл не следует помещать элементы реализации модуля, в том числе и внутренние функции, которые необходимы для реализации, однако не существенны для клиентского когда модуля.
- •Объектная декомпозиция
- •2. Понятие класса и объекта. Переменные-члены и функции-члены. Обращение к членам класса через объект. Указатель this. Константные функции-члены.
- •3. Спецификаторы доступа. Понятие инкапсуляции. Отличие конструкций class и struct. Методы доступа.
- •4. Конструкторы классов, синтаксис, разновидности, моменты вызова конструкторов. Роль конструкторов в соблюдении инвариантов классов.
- •5. Конструкторы по умолчанию (default constructors). Тривиальные и нетривиальные сгенерированные конструкторы классов. Конструирование массивов объектов.
- •6. Списки инициализации. Синтаксис, отличие от присвоений в теле конструктора, необходимость в существовании.
- •7. Деструкторы классов, синтаксис, цель, моменты вызова деструкторов.
- •8. Моменты копирования объектов. Поведение по умолчанию. Конструктор копий и оператор копирующего присвоения.
- •9. Временные объекты. Явные и неявные конструкторы. Оптимизации rvo/nrvo. Временные объекты
- •Неявные и явные конструкторы
- •Запрещение копирования
- •Оптимизация копирования
- •10. Основные отличия между классами-значениями и классами-сущностями. Запрещение копирования объектов. Основные отличия между классами-значениями и классами-сущностями.
- •11. Перемещение объектов. Конструктор перемещения и оператор перемещающего присвоения. Понятие rvalue-ссылки. Функция std::move.
- •12. Перегрузка операторов. Оправданное и неоправданное использование. Пример перегрузки простейшего оператора. Операторы, которые нельзя перегружать.
- •13. Внутриклассовые и глобальные перегруженные операторы. Перегрузка операторов сдвига. Применение перегрузки сдвига для взаимодействия с потоками ввода/вывода.
- •14. Перегрузка операторов сравнения и арифметических операторов. Основные правила реализации и применения.
- •15. Перегрузка операторов индексной выборки, префиксного и постфиксного инкремента/декремента. Перегрузка операторов преобразования типа.
- •16. Статические переменные-члены. Цель применения. Синтаксис. Особенности компоновки.
- •17. Статические функции-члены. Синтаксис, особенности применения. Фабричный метод. Статические функции-члены
- •Фабричный метод
- •19. Физическое и логическое постоянство объектов. Модификатор mutable.
- •20. Класс std::string из стандартной библиотеки. Основная функциональность, способы применения. Особенности внутренней структуры.
- •21. Композиция объектов. Иерархии целое-часть. Структура простейшей композиции по значению в памяти. Ответственность за уничтожение объектов при композиции.
- •22. Ссылочная композиция. Разрываемая композиция. Кратность композиции. Одиночная, множественная и недетерминированная кратность.
- •23. Применение контейнера std::vector для композиции с недетерминированной кратностью. Композиция объектов-значений и объектов-сущностей.
- •24. Композиция объектов с кратностью многие-ко-многим. Основные особенности объектных отношений, способы реализации.
- •25. Наследование классов. Необходимость в отношении наследования. Структура наследования в памяти. Повышающее преобразование типа.
- •26. Критерии оценки корректности применения наследования. Примеры корректного и некорректного применения наследования.
- •27. Конструкторы и деструкторы при наследовании. Моменты и порядок вызовов конструкторов. Передача аргументов конструкторам базового класса.
- •28. Спецификатор доступа protected. Защищенные конструкторы и методы.
- •29. Понижающее преобразование типа (downcast). Опасности. Поля идентификации типов.
- •30. Виртуальные функции. Полиморфизм. Цель. Синтаксис, примеры использования.
- •31. Реализация виртуальных функций. Указатель vptr и таблица vtable. Вызов виртуальной функции. Инициализация служебных данных для работы виртуальных функций в конструкторах.
- •32. Контроль переопределения виртуальных функций. Требования к сигнатурам. Ключевые слова override и final. Ковариантность возвращаемых типов.
- •33. Чисто виртуальные функции и абстрактные классы. Вызов чисто виртуальной функции в конструкторе до завершения инициализации объекта.
- •34. Понятие интерфейса. Применение интерфейсов.
- •35. Множественное наследование конкретных классов. Синтаксис, структура в памяти, особенности применения и реализации.
- •36. Преобразование типов при множественном наследовании в верхнем и нижнем направлениях. Коррекция указателя this.
- •37. Множественное наследование классов с повторяющимся базовым. Синтаксис, структура в памяти, особенности применения и реализации.
- •38. Виртуальные базовые классы. Синтаксис, структура в памяти, особенности применения и реализации. Понятие “самого производного” класса и его роль в организации работы виртуальных базовых классов.
- •39. Механизм rtti - назначение, особенности применения. Структура std::type_info, оператор typeid для выражений и типов.
- •40. Применение оператора dynamic_cast для указателей и ссылок. Основные цели использования. Отличия от операторов static_cast, reinterpret_cast и const_cast.
- •41. Альтернативные решения, заменяющие dynamic_cast. Виртуальные функции для понижающего преобразования. Типовое решение Visitor.
- •42. Обработка исключений. Цели, синтаксис выброса и обработчиков. Выбор обработчика по типу. Передача данных исключения по значению, указателю и ссылке. Исключения языка и стандартной библиотеки.
- •44. Шаблоны функций и классов. Синтаксис определения шаблонов. Инстанцирование шаблонов. Модель включения и явное инстанцирование.
- •Шаблоны классов
- •45. Аргументы шаблонов - типы, константы, шаблонные аргументы шаблонов. Дедукция фактических аргументов шаблонов.
- •46. Понятие обобщенной концепции. Статический полиморфизм по сравнению с динамическим полиморфизмом.
- •Статический полиморфизм
- •47. Итераторы stl - основные разновидности, итераторы контейнеров, итераторы, не связанные с контейнерами.
- •48. Классификация алгоритмов стандартной библиотеки. Примеры применения наиболее часто используемых алгоритмов.
- •49. Функциональные объекты stl. Простые функциональные объекты. Стандартные функциональные объекты. Связыватели std::bind.
- •50. Понятие лямбда-выражения. Синтаксис, особенности использования. Реализация лямбда-выражений компилятором. Список захвата лямбда-выражения.
- •51. Специализация шаблонов. Полная и частичная специализация. Статический выбор вариантов на основе специализации шаблонов.
- •52. Необычный рекуррентный шаблон. Структура, варианты применения.
Статический полиморфизм
Обобщенные концепции в целом напоминают абстрактные классы - интерфейсы. От фактического типа, при помощи которого допускается инстанцировать алгоритм, требуется наличие конкретного набора определенных операций (в случае итератора для алгоритма поиска этот набор включает присвоение, сравнение, постфиксный инкремент, разыменование с целью чтения). Однако, в отличие от интерфейсов, обобщенные концепции в явном виде никаким образом в коде не задаются (идеи явного выражения требований к обобщенной концепции рассматривались при принятии стандарта C++11, однако в итоге не стали частью языка из-за разногласий экспертов). Код шаблонов просто использует необходимые для реализации операции, и предполагает, что конкретный тип их предоставит. Если это не соответствует действительности в момент инстанцирования, компилятор не позволит инстанцировать шаблон с таким типом аргумента.
Обобщенные концепции иногда называют инструментом СТАТИЧЕСКОГО ПОЛИМОРФИЗМА, В отличие от обычного, или динамического полиморфизма, реализуемого на основе механизма виртуальных функций, такая форма полиморфизма имеет ряд преимуществ и недостатков. К плюсам относится следующее:
· нет необходимости в явном написании ограничивающих базовых классов или интерфейсов, возможность дополнять интерфейс чем угодно;
· отсутствуют накладные расходы на вызов во время выполнения, в отличие от виртуальных функций, работающих через косвенные вызовы через указатель vptr;
· возможность частичной реализации общего интерфейса, если остальные случаи не используются (и соответственно, не подлежат инстанцированию и проверкам).
К минусам, по сравнению с динамическим полиморфизмом, можно отнести такие свойства:
· нельзя привести указатели и ссылки к какому-либо базовому классу, а значит нельзя создать массив/контейнер указателей на объекты базового класса;
· компиляция шаблонов приведет к большему объему генерируемого машинного кода и увеличению времени компиляции.
Ниже приведен пример системы объектов, реализованных сначала с использованием динамического полиморфизма на основе абстрактного класса и виртуальных функций, а затем аналогичный пример с использованием статического полиморфизма на основе шаблонов.
В примере речь идет о двух различных системах оценивания студентов - классической 5-бальной советской системы и используемой в высших учебных заведения в настоящее время Болонской 100-бальной системы. К центральной абстракции - таблице оценок студентов (класс AcademicGroupMarks) - подключается конкретный объект, отвечающий за выбранную систему оценивания. Задача системы оценивания состоит в определении организационного вывода в зависимости от набранного балла - неудача, сдача без стипендии, сдача со стипендией.
Начнем с динамического варианта. Потребуется создать интерфейс MarkSystem и описать необходимые для взаимодействия виртуальные функции. Затем этот интерфейс нужно реализовать в двух классах - SovietMarkSystem и BolognaMarkSystem. Конкретный объект системы оценивания создается динамически и прикрепляется к объекту AcademicGroupMarks, образуя отношение композиции с ответственностью за уничтожение. Взаимодействие с дочерним объектом происходит через механизм виртуальных функций.
Аналогичной функциональности можно добиться применяя статический полиформизм. Среди основных отличий реализации от динамической версии следующее:
отсутствует необходимость в интерфейсе MarkSystem, поскольку обобщенные концепции в явном виде не описываются;
методы классов BolognaMarkSystem и SovietMarkSystem более не виртуальные, а статические;
связь между таблицей оценок и системой оценивания реализуется без создания объектов на основе аргумента шаблона;
таблица оценок более не нуждается в конструкторе.
Поскольку набор фактических аргументов шаблона конечен и заранее известен, применяется модель явного инстанцирования шаблона.
Результат выполнения аналогичен динамическому варианту. Программируя в таком стиле представляется возможным получить потенциально более быстродействующее решение за счет отказа от виртуальных функций. За лучшие показатели во время выполнения придется заплатить более долгим временем компиляции и, скорее всего, бОльшим временем, необходимым программисту для создания стабильной реализации.