Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы по ООП 2023 / Вопросы к экзамену С ОТВЕТАМИ.docx
Скачиваний:
0
Добавлен:
09.09.2026
Размер:
78 Кб
Скачать
  • Конструктор вызывается при создании объекта. Оператор присваивания если объект уже существует.

  1. Что такое конструктор перемещения? Для чего он нужен? В каким случаях он вызывается неявно?

Конструктор перемещения (move constructor) представляет альтернативу конструктору копирования в тех ситуациях, когда надо сделать копию объекта, но копирование данных нежелательно - вместо копирования данных они просто перемещаются из одной копии объекта в другую.

Возврат объекта из функции.

  • Позволяет избегать излишнего копирования

  • Основывается на move-семантике (std::move и std::swap)

  • Правило: если определен конструктор перемещения, то необходимо реализовать оператор присваивания с перемещением

  • swap - меняет местами значения. move - перемещает значения откуда-то

  1. К чему может быть применено ключевое слово const? Какие эффекты оно имеет?

  • Ключевое слово const позволяет определять типизированные константы

  • Попытка изменений таких значений пресекается компилятором

  • Константные поля класса изменять нельзя. Должны быть инициализированы в момент создания объекта класса

  • У константных объектов класса нельзя изменять поля, почти всегда.

  • Методы классов и структур могут быть помечены модификатором const

  • Такие методы не могут изменять поля объекта

  • Указатель this является Type const * this в константных методах

  • У константных объектов можно вызывать только константные методы

  • Является частью сигнатуры метода

  1. К чему может быть применено ключевое слово mutable? Какие эффекты оно имеет?

Иногда бывает необходимо, чтобы какие-то данные константного объекта все-таки можно было менять. В этом случае для переменной, которую необходимо менять, можно использовать ключевое слово mutable. И даже если объект является константным, значение такой переменной можно изменить.

mutable показывает, что член класса является изменяемым, и его можно изменять в функциях, у которых указан модификатор const, а также у константных объектов.

  • Позволяет определять поля, доступные для изменения внутри константных методов

  • Рекомендуется использовать только с полями, не являющимися частью состояния объекта

  1. К чему может быть применено ключевое слово static? Какие эффекты оно имеет?

Static — это ключевое слово в C++, используемое для придания элементу особых характеристик. Для статических элементов выделение памяти происходит только один раз и существуют эти элементы до завершения программы.

Объекты доступны всем.

  • Модификатор static создает поле класса, разделяемое между всеми объектами класса

  • static поле инициализируется во время запуска программы

  • Изменение static поля в одном объекте класса видно во всех остальных объектах класса

  • static метод класса «не привязан» к объектам класса

  • static метод класса может обращаться только к static полям класса

  • static метод не имеет доступа к идентификатору this

  • static методы “нарушают” принципы ООП

  1. В чем особенности конструктора от одного аргумента? Как можно изменить вызов конструктора от одного аргумента?

Компилятору разрешено выполнить одно неявное преобразование для преобразования параметров в функцию. Это означает, что компилятор может использовать конструкторы, вызываемые с единственным параметром, для преобразования из одного типа в другой, чтобы получить правильный тип для параметра. Добавление префикса explicit ключевому слову к конструктору не позволяет компилятору использовать этот конструктор для неявных преобразований.

  1. Что такое списки инициализации? Как можно в метод передать любое количество значение одного типа данных?

initializer_list позволяет передать в качестве аргументов массив значений.

  • Предназначены для инициализации полей при создании объекта

  • Инициализация происходит в порядке объявления полей в классе

  • Позволяет инициализировать константные поля

  1. Что такое делегирующий конструктор? Как влияют значения по умолчанию на вызов конструкторов?

  • Позволяет вызывать конструктор из конструктора того же класса

  • Сокращает дублирование кода

Чтобы добавить делегированные конструкторы, используйте constructor (. . .) : constructor (. . .).

  1. Как можно запретить копирование и перемещение объекта?

  • Можно удалить конструкторы, указав = delete

  • Также можно удалить конструктор по умолчанию.

  1. Что такое оператор? Какие виды операторов есть?

Оператор – функция, обозначенная специальным символом.

Арифметические операторы, Операторы сравнения, Логические операторы, Побитовые операторы, Составное присваивание, Операторы работы с указателями и членами класса.

  1. Какие особенности перегрузки оператора приведения к типу?

  • Особенность – не имеет возвращаемого типа

  • Можно приводить к любому типу, известному в месте объявления оператора

  • Должен быть методом класса

  1. Особенности перегрузки унарного инкремента и декремента?

  • Префиксный оператор не принимает аргументов и сначала меняет объект, потом возвращает ссылку на него

  • Постфиксный оператор принимает фиктивный аргумент, создает копию объекта, меняет текущий объект и возвращает копию по значению

  1. Расположение полей классов при наследовании?

Члены класса(структуры) конструируются и располагаются по такому же порядку, по которому они были объявлены (порядок инициализации не имеет значения).

Сначала дочерние потом родители.

  • Все поля базового класса содержатся в производном

  • Использование класса в качестве базового эквивалентно созданию неименованного поля в дочернем объекте

  • Внутренний объект родительского класса располагается в начале дочернего объекта

  • Для использования в качестве базового, класс должен быть объявлен перед этим

  1. Как модификаторы доступа влияют на члены класса при наследовании?

Происходит понижение к самому ограничивающему модификатору доступа:

  • public наследование ничего не меняет

  • protected наследование делает из public полей protected

  • private наследование делает все поля private

  1. Какой порядок создания и уничтожения объекта класса при наследовании?

Если и у базового, и у производного классов есть конструкторы и деструкторы, то конструкторы выполняются в порядке наследования, а деструкторы – в обратном порядке. То есть если А – базовый класс, В – производный из А, а С – производный из В (А-В-С), то при создании объекта класса С вызов конструкторов будет иметь следующий порядок:

конструктор класса А -> конструктор класса В -> конструктор класса С.

Вызов деструкторов при удалении этого объекта произойдет в обратном порядке:

деструктор класса С -> деструктор класса В -> деструктор класса А.

Порядок вызовов конструкторов:

  • Конструкторы виртуальных базовых классов

  • Конструкторы прямых базовых классов

  • Конструкторы полей

  • Конструктор класса

  1. Что такое переопределение метода? Какие есть особенности вызова переопределенного метода?

  • Переопределение функций – создание метода в дочернем классе с сигнатурой, совпадающей с методом в родительском классе

  • Для определения вызываемого метода компилятор сначала ищет его в дочернем классе, если не находит, то ищет в базовых классах по цепочке наследования

  • Переопределение функций позволяет изменять поведение базового класса. Является статическим полиморфизмом.

  1. Что такое дружественная функция/класс? В чем особенности? Какое поведение при наследовании?

  • Дружественные функции:

  1. Имеют доступ к private и protected полям класса

  2. Не являются методом класса

  3. Дружественность объявляется внутри класса спецификатором friend

  • Дружественность не наследуется

  • Дружественность напрямую нарушает принцип инкапсуляции. Поэтому нужно использовать в исключительных ситуациях и только для read-only доступах

  • Дружественный класс имеет доступ к private и protected полям класса

  • Все методы дружественного класса становятся дружественными

  1. Какие особенности приведения объекта производного класса к базовому?

Преобразовать от производного к базовому классу можно только с помощью указателя или ссылки.

Base& b2 = d2; //ОК

Base* b3 = new Deriv(); //ОК

  • Это возможно за счет одинакового расположения полей

  1. Что такое виртуальный метод? Какие ограничения есть на виртуальный метод?

Виртуальный метод — метод (функция) класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения.

Объект абстрактного класса создать нельзя. Наследники абстрактного класса должны предоставить реализацию для всех его абстрактных методов, иначе они, в свою очередь, будут абстрактными классами.

  • Методы класса, которые предполагается переопределить в производных классах

  • Вызывает метод производного класса даже через ссылку или указатель на базовый класс

  • Модификатор virtual располагается перед типом возвращаемого значения

  • Метод должен быть определен виртуальным в месте первого объявления

  1. Что такое полиморфный класс? Что такое абстрактный класс? Что такое класс-интерфейс?

Абстрактный класс, содержащий по крайней мере один чистый виртуальный метод, является абстрактным.

Полиморфный класс:

  • Любой класс, содержащий по крайней мере один виртуальный метод, является полиморфным

  • Каждый объект такого класса содержит таблицу виртуальных методов (vtable)

  • При использовании ссылки / указателя разрешение методов происходит динамически в момент вызова

Интерфейсом является класс:

  • все члены которого объявлены как public

  • содержит только чистые виртуальные методы

  • не содержит никаких полей-данных

  1. К чему может быть применено ключевое слово final? Как эффекты имеет?

  • Для виртуальных методов может обозначать, что это конечное переопределение

  • Не может применяться к не виртуальным методам

  • Для класса определяет, что от него нельзя дальше наследоваться

  • Для определения финального класса может использовать std::is_final

  1. Что такое виртуальное наследование? Для чего оно нужно?

  • Необходимо явно вызывать конструкторы всех виртуально унаследованных классов

  • Необходимо соблюдать правило “Наследовать можно только от одного класса, реализовывать можно много интерфейсов”

  • Опасность вызова функции из класса «брата»

Виртуальное наследование предотвращает проблему множественного наследования.

  1. Что такое шаблонная функция/класс? К какому виду полиморфизма относятся шаблоны и почему?

  • Шаблоны— средство, предназначенное для написания обобщенных алгоритмов без привязки к некоторым параметрам (например, типам данных, размерам буферов, значениям по умолчанию)

  • Шаблоны приводят к парадигме обобщенного программирования (метапрограммирования)

  • беспечивают статический полиморфизм

  1. Что можно указывать в качестве параметра шаблона?

Типы данных, константы, несколько типов данных, множественные параметры, с переменным числом параметров.

  1. Что такое инстанцирование шаблона?

  • Шаблоны не компилируются до инстанцирования, то есть пока не будет попытки их использовать

  • Сгенерированный шаблон – полноценный класс или функция

  • Шаблоны необходимо определять в header файлах, так как нельзя отдельно компилировать шаблон без известных типов и/или значений

  1. Что такое исключительная ситуация? Какие традиционные механизмы их обработки есть?

Исключительная ситуация – это ошибка, которая возникает во время выполнения программы, не планируемая заранее.

  • Остановка программы

  • Возврат кода ошибки из вызванного метода

  • Запись кода ошибки в аргумент функции

  • Сообщение об ошибке через глобальную переменную

  • Монады - инструмент функциональных ЯП

  • Механизм исключений

  1. Что такое механизм исключений? Как он реализован в языке С++?

  • Альтернатива традиционным техникам

  • Позволяет разработчикам разделить код на:

  1. Реализующий естественное поведение программы

  2. Обрабатывающий исключительные ситуации

  • Предоставляет единый стиль обработки ошибок

  • Используются, когда код решения проблемы находится не рядом с местом её возникновения

  • Рекомендуется использовать специальные типы для объектов, которые «бросаются» в исключительных ситуациях

  1. Что такое раскрутка стека при исключении? Что происходит, если исключение не обработано?

  • Если не найден catch, способный обработать исключение, производится поиск на вышестоящих уровнях

  • Раскрутка происходит до точки входа в приложение

  • Если не было встречено подходящего обработчика – исключение считается не обработанным

  • В таком случае вызывается функция terminate() – текущий обработчик завершения

  • По умолчанию он реализован как abort()

  • Изменение функции-обработчика завершения через set_terminate(terminateHandler)

  1. Какие гарантии исключений есть? В чем их различия? Для чего нужно ключевое слово noexcept и какие особенности его применения?

  • Basic - соблюдается базовый инвариант для всех объектов, нет утечки ресурсов. Состояние может измениться.

  • Strong - дополнительно операция выполняется либо полностью, либо не имеет эффекта совсем. Соблюдается транзакционность.

  • Nothrow (Noexcept) - гарантируется отсутствие возбуждения исключения при выполнении операции.

noexcept

  1. Используется для снижения накладных расходов механизма исключений

  2. Гарантирует, что функция не генерирует исключения в процессе выполнения

  3. Если же это произойдет – будет вызвана функция terminate() без раскрутки стека

  4. Программа скомпилируется с предупреждением. Исключение не будет перехвачено.

  1. Что такое умный указатель? В чем особенности std::unique_ptr?

  • Реализуют идиому RAII

  • Контролируют время жизни объекта

  • Реализуют тот же интерфейс, что и «сырой» указатель

  • Обеспечивают безопасность исключений

  • Умные указатели замедляют скорость работы программы

  1. Находится в модуле memory

  2. Владеет объектом единолично

  3. Нельзя копировать, но можно перемещать

  4. Не рекомендуется хранить в stl контейнерах

  5. Есть функция release и get для получения чистого указателя

  6. Метод reset позволяет очистить указатель

  7. Приводится к типу bool для проверки хранения

  1. Что такое std::shared_ptr и std::weak_ptr? Из чего состоит std::shared_ptr? Какая у них связь? В чем их особенности?

std::shared_ptr

  • Содержит множество ссылок на объект

  • Объект удаляется, когда на него не остается ссылок

shared_ptr – свойства

  • Удобен для разделения владения

  • Можно возвращать из функции

  • Можно класть в любые stl контейнеры

  • use_count – позволяет узнать кол-во ссылок на объект

  • unique – проверяет единственность владения

  • Можно приводить к другим типам:

Блок управления shared_ptr

  • Указатель на управляемый объект или сам управляемый объект

  • Функцию удаления объекта

  • Функция аллокации объекта

  • Счетчик указателей shared_ptr, владеющих управляемым объектом

  • Счетчик указателей weak_ptr, которые ссылаются на управляемый объект

std::weak_ptr

  • Содержит «слабую» ссылку на объект, управляемый shared_ptr

  • Можно превратить в shared_ptr функцией lock

  • expired позволяет проверить, существует ли объект

  • Нельзя разыменовать

  1. Что такое лямбда-функция в C++? Из чего состоит?

Лямбда-функция – вариант реализации функциональных объектов, обязанный своим названием λ-исчислению – математической системе определения и применения функций, в которой аргументом одной функции может быть другая функция. Лямбда-функции в основном определяются в точке их применения. Лямбда-функции могут использоваться всюду, где требуется передача вызываемому объекту функции соответствующего типа.

  • Является анонимной функцией

  • Можно хранить в переменных

  • Обычно используются для однострочных и редко используемых функций

  • Упрощенный синтаксис лямбда-функции в C++: [блок захвата] (аргументы) {тело функции}

Соседние файлы в папке Лабы по ООП 2023