Ключевое слово this
this используется для ссылки на текущий объект класса. Это слово инициализируется при создании объекта и доступно во всех методах объекта.
В примере в методе getArea() используется this для доступа к переменным width и height текущего объекта rect.
Результат работы программы:
Площадь: 12
#это_база
this используется для ссылки на текущий объект класса. Это слово инициализируется при создании объекта и доступно во всех методах объекта.
В примере в методе getArea() используется this для доступа к переменным width и height текущего объекта rect.
Результат работы программы:
Площадь: 12
#это_база
#вопросы_с_собеседований
Для чего нужен был тип std::auto_ptr<T>?
Тип std::auto_ptr<T> использовался для автоматического управления памятью и представляет собой умный указатель на объект типа T.
auto_ptr упрощает управление памятью и исключает утечки памяти из-за забытого вызова delete. Однако в современном C++ auto_ptr считается устаревшим и заменен на std::unique_ptr.
Для чего нужен был тип std::auto_ptr<T>?
auto_ptr упрощает управление памятью и исключает утечки памяти из-за забытого вызова delete. Однако в современном C++ auto_ptr считается устаревшим и заменен на std::unique_ptr.
Умные указатели в С++
Умные указатели - это шаблоны классов, которые позволяют автоматически управлять памятью и не допускать утечек.
Среди основных умных указателей:
- unique_ptr - указатель, который владеет объектом в единственном экземпляре.
- shared_ptr - указатель, у которого может быть несколько владельцев.
- weak_ptr - указатель на объект, владельцем которого является shared_ptr.
#это_база
Умные указатели - это шаблоны классов, которые позволяют автоматически управлять памятью и не допускать утечек.
Среди основных умных указателей:
- unique_ptr - указатель, который владеет объектом в единственном экземпляре.
- shared_ptr - указатель, у которого может быть несколько владельцев.
- weak_ptr - указатель на объект, владельцем которого является shared_ptr.
#это_база
#вопросы_с_собеседований
В каком порядке инициализируются и уничтожаются члены класса?
Сначала вызываются конструкторы базовых классов в порядке наследования.
Затем инициализируются члены класса в порядке их объявления в классе.
После этого вызывается конструктор текущего класса.
Аналогичным образом происходит уничтожение объекта:
Сначала вызывается деструктор текущего класса.
Затем уничтожаются члены класса в порядке, обратном их инициализации.
Далее вызываются деструкторы базовых классов в обратном порядке наследования.
В каком порядке инициализируются и уничтожаются члены класса?
Затем инициализируются члены класса в порядке их объявления в классе.
После этого вызывается конструктор текущего класса.
Аналогичным образом происходит уничтожение объекта:
Сначала вызывается деструктор текущего класса.
Затем уничтожаются члены класса в порядке, обратном их инициализации.
Далее вызываются деструкторы базовых классов в обратном порядке наследования.
std::find
std::find - это алгоритм из стандартной библиотеки, который ищет элемент в контейнере.
Он принимает 3 аргумента:
- Итератор на начало контейнера
- Итератор на конец контейнера
- Искомое значение
И возвращает итератор на найденный элемент или итератор на конец, если элемент не найден.
В примере мы ищем элемент со значением 3 в векторе vec. std::find возвращает итератор на найденный элемент, по которому мы выводим значение.
std::find - это алгоритм из стандартной библиотеки, который ищет элемент в контейнере.
Он принимает 3 аргумента:
- Итератор на начало контейнера
- Итератор на конец контейнера
- Искомое значение
И возвращает итератор на найденный элемент или итератор на конец, если элемент не найден.
В примере мы ищем элемент со значением 3 в векторе vec. std::find возвращает итератор на найденный элемент, по которому мы выводим значение.
Функция all_of
std::all_of - это алгоритм из стандартной библиотеки, который позволяет проверить, удовлетворяют ли все элементы диапазона какому-либо условию.
В примере мы создаем вектор целых чисел v и используем all_of, чтобы проверить, что все элементы больше нуля. Для этого передаем в all_of итераторы на начало и конец вектора, а также лямбда-функцию, которая проверяет, что элемент больше нуля.
#это_база
std::all_of - это алгоритм из стандартной библиотеки, который позволяет проверить, удовлетворяют ли все элементы диапазона какому-либо условию.
В примере мы создаем вектор целых чисел v и используем all_of, чтобы проверить, что все элементы больше нуля. Для этого передаем в all_of итераторы на начало и конец вектора, а также лямбда-функцию, которая проверяет, что элемент больше нуля.
#это_база
Libusb
Libusb - это кросплатформенная библиотека для работы с USB-устройствами из приложений. Она позволяет обращаться к USB-устройствам, считывать и записывать данные, управлять конфигурацией устройств.
Libusb часто используется для создания приложений, которым нужно низкоуровневое USB-взаимодействие - драйверов устройств, утилит настройки оборудования, средств тестирования и отладки.
Этот код инициализирует libusb, открывает устройство по заданному VID/PID, читает данные bulk-передачей, обрабатывает их, и закрывает соединение с устройством.
Libusb - это кросплатформенная библиотека для работы с USB-устройствами из приложений. Она позволяет обращаться к USB-устройствам, считывать и записывать данные, управлять конфигурацией устройств.
Libusb часто используется для создания приложений, которым нужно низкоуровневое USB-взаимодействие - драйверов устройств, утилит настройки оборудования, средств тестирования и отладки.
Этот код инициализирует libusb, открывает устройство по заданному VID/PID, читает данные bulk-передачей, обрабатывает их, и закрывает соединение с устройством.
#вопросы_с_собеседований
Какие накладные расходы связаны с вызовом виртуальной функции?
При вызове виртуальной функции происходят следующие накладные расходы:
1. Поиск в таблице виртуальных функций (vtable):
для вызова виртуальной функции компилятор должен сначала получить указатель на нужную функцию из vtable класса. Это занимает некоторое время.
2. Невозможность инлайнинга:
тело виртуальной функции неизвестно на этапе компиляции, поэтому оптимизация инлайнинга для таких функций невозможна.
4. Затраты памяти на vtable:
для каждого класса с виртуальными функциями нужно хранить таблицу vtable, что увеличивает расход памяти.
Какие накладные расходы связаны с вызовом виртуальной функции?
1. Поиск в таблице виртуальных функций (vtable):
для вызова виртуальной функции компилятор должен сначала получить указатель на нужную функцию из vtable класса. Это занимает некоторое время.
2. Невозможность инлайнинга:
тело виртуальной функции неизвестно на этапе компиляции, поэтому оптимизация инлайнинга для таких функций невозможна.
4. Затраты памяти на vtable:
для каждого класса с виртуальными функциями нужно хранить таблицу vtable, что увеличивает расход памяти.
std::sort
std::sort - это функция стандартной библиотеки для сортировки элементов в контейнерах, таких как вектор или список.
Чтобы использовать std::sort, нужно подключить заголовочный файл <algorithm>.
Метод принимает в качестве аргументов итераторы на начало и конец сортируемой последовательности и сортирует элементы в возрастающем порядке по умолчанию.
Для определения порядка сортировки можно указать свой компаратор.
#это_база
std::sort - это функция стандартной библиотеки для сортировки элементов в контейнерах, таких как вектор или список.
Чтобы использовать std::sort, нужно подключить заголовочный файл <algorithm>.
Метод принимает в качестве аргументов итераторы на начало и конец сортируемой последовательности и сортирует элементы в возрастающем порядке по умолчанию.
Для определения порядка сортировки можно указать свой компаратор.
#это_база
#вопросы_с_собеседований
В чем разница между статической и динамической библиотеками?
- Статические библиотеки компонуются с программой на этапе компиляции, а динамические подключаются во время выполнения программы.
- Из статической библиотеки в программу копируется только используемый код, а динамическая библиотека подключается целиком.
- Статические библиотеки увеличивают размер конечного файла программы, динамические - нет.
- Если статическая библиотека обновляется, нужно перекомпилировать программу. Для динамической библиотеки достаточно заменить файл библиотеки.
- Статические библиотеки предпочтительны, когда важна скорость выполнения, динамические - когда нужна гибкость и меньший размер программы.
В чем разница между статической и динамической библиотеками?
- Из статической библиотеки в программу копируется только используемый код, а динамическая библиотека подключается целиком.
- Статические библиотеки увеличивают размер конечного файла программы, динамические - нет.
- Если статическая библиотека обновляется, нужно перекомпилировать программу. Для динамической библиотеки достаточно заменить файл библиотеки.
- Статические библиотеки предпочтительны, когда важна скорость выполнения, динамические - когда нужна гибкость и меньший размер программы.
Ключевое слово extern
Ключевое слово extern используется для объявления глобальных переменных и функций, реализация которых находится в другом модуле.
Это позволяет разделить интерфейс и реализацию.
Несмотря на разделение кода по файлам, при компиляции программы компоновщик свяжет объявление и реализацию вместе и позволит вызвать print() в main().
Ключевое слово extern используется для объявления глобальных переменных и функций, реализация которых находится в другом модуле.
Это позволяет разделить интерфейс и реализацию.
Несмотря на разделение кода по файлам, при компиляции программы компоновщик свяжет объявление и реализацию вместе и позволит вызвать print() в main().
reference_wrapper
reference_wrapper - это класс-обёртка для ссылок из заголовочного файла <functional>. Он позволяет передавать ссылки как значения.
Основное преимущество в том, что reference_wrapper ведёт себя как ссылка, но может копироваться как значение. Это избавляет от необходимости использовать указатели в подобных сценариях.
В этом примере мы передаем ссылку на переменную value в функцию process, используя std::ref для создания объекта std::reference_wrapper.
В функции process мы можем работать со ссылкой, как если бы она была передана напрямую, используя метод get() для получения самой ссылки.
reference_wrapper - это класс-обёртка для ссылок из заголовочного файла <functional>. Он позволяет передавать ссылки как значения.
Основное преимущество в том, что reference_wrapper ведёт себя как ссылка, но может копироваться как значение. Это избавляет от необходимости использовать указатели в подобных сценариях.
В этом примере мы передаем ссылку на переменную value в функцию process, используя std::ref для создания объекта std::reference_wrapper.
В функции process мы можем работать со ссылкой, как если бы она была передана напрямую, используя метод get() для получения самой ссылки.
Ключевое слово const
Ключевое слово const используется для создания констант и неизменяемых объектов.
- Const для объявления переменных: запрещает изменение объекта после инициализации.
- Const указатели и ссылки: указатель или ссылка на константный объект. Нельзя изменить объект через них, только читать.
- Функции, возвращающие const значения: гарантируют, что функция не изменит объект.
- Const члены класса: нельзя изменить через объект класса.
- Const методы класса: не меняют члены класса. Часто применяются к getter-методам.
#это_база
Ключевое слово const используется для создания констант и неизменяемых объектов.
- Const для объявления переменных: запрещает изменение объекта после инициализации.
- Const указатели и ссылки: указатель или ссылка на константный объект. Нельзя изменить объект через них, только читать.
- Функции, возвращающие const значения: гарантируют, что функция не изменит объект.
- Const члены класса: нельзя изменить через объект класса.
- Const методы класса: не меняют члены класса. Часто применяются к getter-методам.
#это_база
#вопросы_с_собеседований
Что такое рефакторинг?
Рефакторинг - это процесс изменения внутренней структуры программы без изменения ее внешнего поведения.
Рефакторинг кода может применяться в следующих ситуациях:
- Улучшение читаемости и понятности кода.
- Оптимизация производительности.
- Устранение дублирования кода.
Рефакторинг особенно важен при работе над большими проектами, где код многократно изменяется и расширяется. Он позволяет поддерживать кодбейз чистым, современным и масштабируемым.
Что такое рефакторинг?
Рефакторинг кода может применяться в следующих ситуациях:
- Улучшение читаемости и понятности кода.
- Оптимизация производительности.
- Устранение дублирования кода.
Рефакторинг особенно важен при работе над большими проектами, где код многократно изменяется и расширяется. Он позволяет поддерживать кодбейз чистым, современным и масштабируемым.
std::tuple
std::tuple - это шаблонный класс, представляющий собой фиксированный набор элементов разных типов. Проще говоря, удобный инструмент для упаковки данных разных типов
Элементы tuple инициализируются в конструкторе и доступны только для чтения после создания.
tuple часто используется в комбинации с tie для присваивания кортежа переменным.
#это_база
std::tuple - это шаблонный класс, представляющий собой фиксированный набор элементов разных типов. Проще говоря, удобный инструмент для упаковки данных разных типов
Элементы tuple инициализируются в конструкторе и доступны только для чтения после создания.
tuple часто используется в комбинации с tie для присваивания кортежа переменным.
#это_база
#вопросы_с_собеседований
Что такое union?
Union - это специальный класс, который позволяет хранить данные разных типов в одной области памяти.
Основные характеристики:
- Объявляется с ключевым словом union.
- В каждый момент активно только одно поле.
- Размер равен наибольшему полю.
- Позволяет интерпретировать одну область памяти разными способами.
- Экономит память.
- Доступ к полям как в обычном классе.
Что такое union?
Основные характеристики:
- Объявляется с ключевым словом union.
- В каждый момент активно только одно поле.
- Размер равен наибольшему полю.
- Позволяет интерпретировать одну область памяти разными способами.
- Экономит память.
- Доступ к полям как в обычном классе.
msg_ptr (message pointer)
msg_ptr это указатель на структуру или класс, который содержит данные сообщения. Обычно это просто указатель void*.
Он используется в многопоточном программировании для передачи сообщений между потоками.
Использование указателей вместо копирования данных позволяет избежать лишних копий и ускорить передачу сообщений между потоками.
Если запустить код из примера, можно увидеть, что данные успешно передаются между потоками через очередь с использованием указателей на сообщения.
msg_ptr это указатель на структуру или класс, который содержит данные сообщения. Обычно это просто указатель void*.
Он используется в многопоточном программировании для передачи сообщений между потоками.
Использование указателей вместо копирования данных позволяет избежать лишних копий и ускорить передачу сообщений между потоками.
Если запустить код из примера, можно увидеть, что данные успешно передаются между потоками через очередь с использованием указателей на сообщения.
Функция before_begin()
Метод before_begin() контейнера forward_list возвращает итератор, указывающий на позицию перед первым элементом списка.
Это полезно, например, чтобы вставить элемент в начало списка.
Работает за константное время O(1), т.к. получает ссылку на начало списка.
#это_база
Метод before_begin() контейнера forward_list возвращает итератор, указывающий на позицию перед первым элементом списка.
Это полезно, например, чтобы вставить элемент в начало списка.
Работает за константное время O(1), т.к. получает ссылку на начало списка.
#это_база
try_emplace
Метод try_emplace() в C++17 - это один из способов вставки элемента в ассоциативный контейнер (например, map или unordered_map).
Позволяет вставить новый элемент по ключу, если такого ключа еще нет в контейнере.
Если ключ уже существует, то ничего не происходит.
Преимущества:
- Более эффективно, чем insert, т.к. сразу конструирует элемент на месте.
- Не делает лишних копирований или перемещений.
- Позволяет избежать ненужного перезаписывания элемента по существующему ключу.
Метод try_emplace() в C++17 - это один из способов вставки элемента в ассоциативный контейнер (например, map или unordered_map).
Позволяет вставить новый элемент по ключу, если такого ключа еще нет в контейнере.
Если ключ уже существует, то ничего не происходит.
Преимущества:
- Более эффективно, чем insert, т.к. сразу конструирует элемент на месте.
- Не делает лишних копирований или перемещений.
- Позволяет избежать ненужного перезаписывания элемента по существующему ключу.
#вопросы_с_собеседований
Почему std::make_pair больше не нужна?
В новых стандартах C++ она утратила актуальность по нескольким причинам:
— Появились инициализаторы со скобками {} для создания std::pair напрямую.
— Для вставки в контейнеры теперь есть функция emplace(), которая конструирует элемент прямо на месте.
— Можно использовать агрегатную инициализацию.
— Инициализаторы из C++17 позволяют сразу указывать ключ и значение.
Почему std::make_pair больше не нужна?
— Появились инициализаторы со скобками {} для создания std::pair напрямую.
— Для вставки в контейнеры теперь есть функция emplace(), которая конструирует элемент прямо на месте.
— Можно использовать агрегатную инициализацию.
— Инициализаторы из C++17 позволяют сразу указывать ключ и значение.
insert_or_assign
insert_or_assign — это функция из стандартной библиотеки языка C++, добавленная в C++17. Она используется для вставки элемента в ассоциативный контейнер (например, std::map) или обновления значения элемента, если ключ уже существует.
Преимущества перед operator[]:
— Более безопасна, так как проверяет существование элемента.
— Избавляет от лишнего кода для проверки наличия ключа.
insert_or_assign — это функция из стандартной библиотеки языка C++, добавленная в C++17. Она используется для вставки элемента в ассоциативный контейнер (например, std::map) или обновления значения элемента, если ключ уже существует.
Преимущества перед operator[]:
— Более безопасна, так как проверяет существование элемента.
— Избавляет от лишнего кода для проверки наличия ключа.