- •Группа 1
- •Что такое класс? Что такое объект? Какая связь между классом и объектом?
- •В чем особенности вызова конструкторов базового класса из производного?
- •Ключевое слово using
- •Группа 2
- •Конструктор вызывается при создании объекта. Оператор присваивания если объект уже существует.
- •К чему может быть применено ключевое слово static? Какие эффекты оно имеет?
Конструктор вызывается при создании объекта. Оператор присваивания если объект уже существует.
Что такое конструктор перемещения? Для чего он нужен? В каким случаях он вызывается неявно?
Конструктор перемещения (move constructor) представляет альтернативу конструктору копирования в тех ситуациях, когда надо сделать копию объекта, но копирование данных нежелательно - вместо копирования данных они просто перемещаются из одной копии объекта в другую.
Возврат объекта из функции.
Позволяет избегать излишнего копирования
Основывается на move-семантике (std::move и std::swap)
Правило: если определен конструктор перемещения, то необходимо реализовать оператор присваивания с перемещением
swap - меняет местами значения. move - перемещает значения откуда-то
К чему может быть применено ключевое слово const? Какие эффекты оно имеет?
Ключевое слово const позволяет определять типизированные константы
Попытка изменений таких значений пресекается компилятором
Константные поля класса изменять нельзя. Должны быть инициализированы в момент создания объекта класса
У константных объектов класса нельзя изменять поля, почти всегда.
Методы классов и структур могут быть помечены модификатором const
Такие методы не могут изменять поля объекта
Указатель this является Type const * this в константных методах
У константных объектов можно вызывать только константные методы
Является частью сигнатуры метода
К чему может быть применено ключевое слово mutable? Какие эффекты оно имеет?
Иногда бывает необходимо, чтобы какие-то данные константного объекта все-таки можно было менять. В этом случае для переменной, которую необходимо менять, можно использовать ключевое слово mutable. И даже если объект является константным, значение такой переменной можно изменить.
mutable показывает, что член класса является изменяемым, и его можно изменять в функциях, у которых указан модификатор const, а также у константных объектов.
Позволяет определять поля, доступные для изменения внутри константных методов
Рекомендуется использовать только с полями, не являющимися частью состояния объекта
К чему может быть применено ключевое слово static? Какие эффекты оно имеет?
Static — это ключевое слово в C++, используемое для придания элементу особых характеристик. Для статических элементов выделение памяти происходит только один раз и существуют эти элементы до завершения программы.
Объекты доступны всем.
Модификатор static создает поле класса, разделяемое между всеми объектами класса
static поле инициализируется во время запуска программы
Изменение static поля в одном объекте класса видно во всех остальных объектах класса
static метод класса «не привязан» к объектам класса
static метод класса может обращаться только к static полям класса
static метод не имеет доступа к идентификатору this
static методы “нарушают” принципы ООП
В чем особенности конструктора от одного аргумента? Как можно изменить вызов конструктора от одного аргумента?
Компилятору разрешено выполнить одно неявное преобразование для преобразования параметров в функцию. Это означает, что компилятор может использовать конструкторы, вызываемые с единственным параметром, для преобразования из одного типа в другой, чтобы получить правильный тип для параметра. Добавление префикса explicit ключевому слову к конструктору не позволяет компилятору использовать этот конструктор для неявных преобразований.
Что такое списки инициализации? Как можно в метод передать любое количество значение одного типа данных?
initializer_list позволяет передать в качестве аргументов массив значений.
Предназначены для инициализации полей при создании объекта
Инициализация происходит в порядке объявления полей в классе
Позволяет инициализировать константные поля
Что такое делегирующий конструктор? Как влияют значения по умолчанию на вызов конструкторов?
Позволяет вызывать конструктор из конструктора того же класса
Сокращает дублирование кода
Чтобы добавить делегированные конструкторы, используйте constructor (. . .) : constructor (. . .).
Как можно запретить копирование и перемещение объекта?
Можно удалить конструкторы, указав = delete
Также можно удалить конструктор по умолчанию.
Что такое оператор? Какие виды операторов есть?
Оператор – функция, обозначенная специальным символом.
Арифметические операторы, Операторы сравнения, Логические операторы, Побитовые операторы, Составное присваивание, Операторы работы с указателями и членами класса.
Какие особенности перегрузки оператора приведения к типу?
Особенность – не имеет возвращаемого типа
Можно приводить к любому типу, известному в месте объявления оператора
Должен быть методом класса
Особенности перегрузки унарного инкремента и декремента?
Префиксный оператор не принимает аргументов и сначала меняет объект, потом возвращает ссылку на него
Постфиксный оператор принимает фиктивный аргумент, создает копию объекта, меняет текущий объект и возвращает копию по значению
Расположение полей классов при наследовании?
Члены класса(структуры) конструируются и располагаются по такому же порядку, по которому они были объявлены (порядок инициализации не имеет значения).
Сначала дочерние потом родители.
Все поля базового класса содержатся в производном
Использование класса в качестве базового эквивалентно созданию неименованного поля в дочернем объекте
Внутренний объект родительского класса располагается в начале дочернего объекта
Для использования в качестве базового, класс должен быть объявлен перед этим
Как модификаторы доступа влияют на члены класса при наследовании?
Происходит понижение к самому ограничивающему модификатору доступа:
public наследование ничего не меняет
protected наследование делает из public полей protected
private наследование делает все поля private
Какой порядок создания и уничтожения объекта класса при наследовании?
Если и у базового, и у производного классов есть конструкторы и деструкторы, то конструкторы выполняются в порядке наследования, а деструкторы – в обратном порядке. То есть если А – базовый класс, В – производный из А, а С – производный из В (А-В-С), то при создании объекта класса С вызов конструкторов будет иметь следующий порядок:
конструктор класса А -> конструктор класса В -> конструктор класса С.
Вызов деструкторов при удалении этого объекта произойдет в обратном порядке:
деструктор класса С -> деструктор класса В -> деструктор класса А.
Порядок вызовов конструкторов:
Конструкторы виртуальных базовых классов
Конструкторы прямых базовых классов
Конструкторы полей
Конструктор класса
Что такое переопределение метода? Какие есть особенности вызова переопределенного метода?
Переопределение функций – создание метода в дочернем классе с сигнатурой, совпадающей с методом в родительском классе
Для определения вызываемого метода компилятор сначала ищет его в дочернем классе, если не находит, то ищет в базовых классах по цепочке наследования
Переопределение функций позволяет изменять поведение базового класса. Является статическим полиморфизмом.
Что такое дружественная функция/класс? В чем особенности? Какое поведение при наследовании?
Дружественные функции:
Имеют доступ к private и protected полям класса
Не являются методом класса
Дружественность объявляется внутри класса спецификатором friend
Дружественность не наследуется
Дружественность напрямую нарушает принцип инкапсуляции. Поэтому нужно использовать в исключительных ситуациях и только для read-only доступах
Дружественный класс имеет доступ к private и protected полям класса
Все методы дружественного класса становятся дружественными
Какие особенности приведения объекта производного класса к базовому?
Преобразовать от производного к базовому классу можно только с помощью указателя или ссылки.
Base& b2 = d2; //ОК
Base* b3 = new Deriv(); //ОК
Это возможно за счет одинакового расположения полей
Что такое виртуальный метод? Какие ограничения есть на виртуальный метод?
Виртуальный метод — метод (функция) класса, который может быть переопределён в классах-наследниках так, что конкретная реализация метода для вызова будет определяться во время исполнения.
Объект абстрактного класса создать нельзя. Наследники абстрактного класса должны предоставить реализацию для всех его абстрактных методов, иначе они, в свою очередь, будут абстрактными классами.
Методы класса, которые предполагается переопределить в производных классах
Вызывает метод производного класса даже через ссылку или указатель на базовый класс
Модификатор virtual располагается перед типом возвращаемого значения
Метод должен быть определен виртуальным в месте первого объявления
Что такое полиморфный класс? Что такое абстрактный класс? Что такое класс-интерфейс?
Абстрактный класс, содержащий по крайней мере один чистый виртуальный метод, является абстрактным.
Полиморфный класс:
Любой класс, содержащий по крайней мере один виртуальный метод, является полиморфным
Каждый объект такого класса содержит таблицу виртуальных методов (vtable)
При использовании ссылки / указателя разрешение методов происходит динамически в момент вызова
Интерфейсом является класс:
все члены которого объявлены как public
содержит только чистые виртуальные методы
не содержит никаких полей-данных
К чему может быть применено ключевое слово final? Как эффекты имеет?
Для виртуальных методов может обозначать, что это конечное переопределение
Не может применяться к не виртуальным методам
Для класса определяет, что от него нельзя дальше наследоваться
Для определения финального класса может использовать std::is_final
Что такое виртуальное наследование? Для чего оно нужно?
Необходимо явно вызывать конструкторы всех виртуально унаследованных классов
Необходимо соблюдать правило “Наследовать можно только от одного класса, реализовывать можно много интерфейсов”
Опасность вызова функции из класса «брата»
Виртуальное наследование предотвращает проблему множественного наследования.
Что такое шаблонная функция/класс? К какому виду полиморфизма относятся шаблоны и почему?
Шаблоны— средство, предназначенное для написания обобщенных алгоритмов без привязки к некоторым параметрам (например, типам данных, размерам буферов, значениям по умолчанию)
Шаблоны приводят к парадигме обобщенного программирования (метапрограммирования)
беспечивают статический полиморфизм
Что можно указывать в качестве параметра шаблона?
Типы данных, константы, несколько типов данных, множественные параметры, с переменным числом параметров.
Что такое инстанцирование шаблона?
Шаблоны не компилируются до инстанцирования, то есть пока не будет попытки их использовать
Сгенерированный шаблон – полноценный класс или функция
Шаблоны необходимо определять в header файлах, так как нельзя отдельно компилировать шаблон без известных типов и/или значений
Что такое исключительная ситуация? Какие традиционные механизмы их обработки есть?
Исключительная ситуация – это ошибка, которая возникает во время выполнения программы, не планируемая заранее.
Остановка программы
Возврат кода ошибки из вызванного метода
Запись кода ошибки в аргумент функции
Сообщение об ошибке через глобальную переменную
Монады - инструмент функциональных ЯП
Механизм исключений
Что такое механизм исключений? Как он реализован в языке С++?
Альтернатива традиционным техникам
Позволяет разработчикам разделить код на:
Реализующий естественное поведение программы
Обрабатывающий исключительные ситуации
Предоставляет единый стиль обработки ошибок
Используются, когда код решения проблемы находится не рядом с местом её возникновения
Рекомендуется использовать специальные типы для объектов, которые «бросаются» в исключительных ситуациях
Что такое раскрутка стека при исключении? Что происходит, если исключение не обработано?
Если не найден catch, способный обработать исключение, производится поиск на вышестоящих уровнях
Раскрутка происходит до точки входа в приложение
Если не было встречено подходящего обработчика – исключение считается не обработанным
В таком случае вызывается функция terminate() – текущий обработчик завершения
По умолчанию он реализован как abort()
Изменение функции-обработчика завершения через set_terminate(terminateHandler)
Какие гарантии исключений есть? В чем их различия? Для чего нужно ключевое слово noexcept и какие особенности его применения?
Basic - соблюдается базовый инвариант для всех объектов, нет утечки ресурсов. Состояние может измениться.
Strong - дополнительно операция выполняется либо полностью, либо не имеет эффекта совсем. Соблюдается транзакционность.
Nothrow (Noexcept) - гарантируется отсутствие возбуждения исключения при выполнении операции.
noexcept
Используется для снижения накладных расходов механизма исключений
Гарантирует, что функция не генерирует исключения в процессе выполнения
Если же это произойдет – будет вызвана функция terminate() без раскрутки стека
Программа скомпилируется с предупреждением. Исключение не будет перехвачено.
Что такое умный указатель? В чем особенности std::unique_ptr?
Реализуют идиому RAII
Контролируют время жизни объекта
Реализуют тот же интерфейс, что и «сырой» указатель
Обеспечивают безопасность исключений
Умные указатели замедляют скорость работы программы
Находится в модуле memory
Владеет объектом единолично
Нельзя копировать, но можно перемещать
Не рекомендуется хранить в stl контейнерах
Есть функция release и get для получения чистого указателя
Метод reset позволяет очистить указатель
Приводится к типу bool для проверки хранения
Что такое 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 позволяет проверить, существует ли объект
Нельзя разыменовать
Что такое лямбда-функция в C++? Из чего состоит?
Лямбда-функция – вариант реализации функциональных объектов, обязанный своим названием λ-исчислению – математической системе определения и применения функций, в которой аргументом одной функции может быть другая функция. Лямбда-функции в основном определяются в точке их применения. Лямбда-функции могут использоваться всюду, где требуется передача вызываемому объекту функции соответствующего типа.
Является анонимной функцией
Можно хранить в переменных
Обычно используются для однострочных и редко используемых функций
Упрощенный синтаксис лямбда-функции в C++: [блок захвата] (аргументы) {тело функции}
