Senior C++ Developer
12.6K subscribers
1.33K photos
3 videos
601 links
Изучаем C++.

По вопросам сотрудничества: @adv_and_pr

РКН: https://www.gosuslugi.ru/snet/676e9a1e4e740947beca35ba
Download Telegram
Модульные тесты

Модульные тесты (или юнит-тесты) — это специальные тестовые программы, которые разработчики создают для проверки отдельных модулей или компонентов своего кода на правильность работы. Модуль в данном контексте представляет собой небольшую, независимую часть программы, которую можно протестировать изолированно от других частей приложения.

Целью модульных тестов является убеждение в том, что каждый компонент работает как задумано и не вызывает ошибок или нежелательного поведения.

#для_начинающих
Placement new

Placement new — это специальный оператор, который позволяет создавать объекты в заданной области памяти, вместо выделения новой памяти для объекта. Это полезно, когда вы хотите явно контролировать расположение объектов в памяти, например, при работе с устройствами ввода-вывода или при реализации собственных аллокаторов.

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

#для_продвинутых
std::search

Функция std::search используется для поиска последовательности элементов в другой последовательности. Она находит первое вхождение подпоследовательности элементов в заданной последовательности и возвращает итератор, указывающий на начало этого вхождения, или итератор, указывающий на конец последовательности, если подпоследовательность не найдена.

#для_начинающих
Cache miss

Cache miss (промах в кэше) в C++ относится к ситуации, когда процессор не может найти нужные данные в кэше, и должен обратиться к более медленной памяти (например ОЗУ), для получения этих данных.

Когда код выполняется на процессоре, процессор пытается загрузить данные или инструкции из кэша первого, второго или третьего уровня (L1, L2, L3 и так далее), прежде чем обращаться к оперативной памяти. Если данные или инструкции отсутствуют в кэше, возникает кэш-промах (cache miss), и процессор должен загрузить их из оперативной памяти, что занимает гораздо больше времени, чем доступ к данным в кэше.

#для_продвинутых
Мocking

Мокирование — это процесс создания имитаций (моков) объектов или компонентов программы, чтобы тестировать код без необходимости использовать реальные зависимости.

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

#для_продвинутых
std::conditional_variable

Стандартная библиотека предоставляет два компонента для работы с многопоточностью: std::thread для создания и управления потоками и std::mutex для обеспечения синхронизации доступа к общим данным. Для синхронизации потоков при ожидании определенных условий используется std::condition_variable.

std::condition_variable представляет собой механизм, который позволяет одному потоку ждать, пока другой поток выполняет определенные действия, и затем оповещать первый поток о завершении выполнения этих действий. Она используется вместе с std::unique_lock (или другими мьютексами) для ожидания изменения состояния.

#для_продвинутых
Конструктор по умолчанию

Конструктор по умолчанию — это конструктор класса, который вызывается без аргументов. Если в классе не определено ни одного конструктора, компилятор автоматически генерирует конструктор по умолчанию. Если же в классе есть пользовательские конструкторы (то есть конструкторы, определенные программистом), компилятор не будет автоматически создавать конструктор по умолчанию.

Конструктор по умолчанию выполняет инициализацию объекта класса, задавая начальные значения его членов. Если класс имеет члены-переменные, они будут инициализированы значениями по умолчанию для своих типов данных (например, числовые типы будут инициализированы нулями, указатели — нулевыми указателями и т.д.).

#для_начинающих
Aggregate initialization

Aggregate initialization (Инициализация агрегатов) — это способ инициализации структур, классов и массивов в C++. Этот способ позволяет инициализировать члены агрегата (поля структуры или класса, элементы массива) при создании объекта без необходимости вызова конструкторов.

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

#для_продвинутых
Run-time type identification

Run-time type identification (RTTI) — это механизм, который позволяет программе определить тип объекта во время выполнения (в рантайме). Это означает, что вы можете определить фактический тип объекта, на который указывает указатель или ссылка, даже если его статический тип (определенный на момент компиляции) отличается.

#для_продвинутых
constexpr

constexpr — это ключевое слово в C++, которое используется для указания компилятору, что функция или переменная может быть вычислена во время компиляции. Это позволяет выполнить некоторые вычисления на этапе компиляции, вместо выполнения их во время выполнения программы.

#для_начинающих
Встраиваемые функции

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

#для_начинающих
static_assert

static_assert — это механизм в C++, который позволяет выполнять проверки на этапе компиляции для статических условий. Он был добавлен в стандарт C++11 и предоставляет способ проверки, что определенное условие истинно во время компиляции. Если условие ложно, компиляция завершится ошибкой.

#для_начинающих
Директива define

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

Следует помнить, что использование макросов может иметь как положительные, так и отрицательные стороны. Они могут улучшить читаемость и обслуживаемость кода, но также могут привести к неожиданным проблемам, таким как ошибки из-за неправильной обработки аргументов макроса или проблемы с пространством имен. В C++ также есть более современные способы достижения тех же целей, такие как константы и inline функции, которые иногда предпочтительнее использовать вместо макросов.

#для_продвинутых
Что такое dynamic_cast?

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

Оператор dynamic_cast применяется преимущественно в контексте полиморфизма, когда у вас есть иерархия классов с виртуальными функциями, и вы хотите выполнить динамическое приведение типов среди объектов этой иерархии.

#для_начинающих
Что такое vptr?

vptr означает «virtual pointer» (виртуальный указатель) и является частью механизма виртуальных функций и полиморфизма.

Когда класс содержит хотя бы одну виртуальную функцию, компилятор добавляет в этот класс скрытый указатель, который называется vptr. Этот указатель указывает на таблицу виртуальных функций, которая называется «таблицей виртуальных функций» или «vtable». В этой таблице содержатся указатели на реализации виртуальных функций для данного класса и всех его производных классов.

#для_начинающих
Что такое const correctness?

Const correctness — это практика написания кода таким образом, чтобы правильно использовать ключевое слово const для обозначения неизменяемости (константности) данных и гарантировать, что эта константность сохраняется во всем коде. Это позволяет улучшить читаемость кода, облегчить его понимание и предостеречь от некоторых типичных ошибок.

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

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

#для_продвинутых
Что такое SFINAE?

SFINAE («Substitution Failure Is Not An Error»), что в переводе с английского означает «Отказ от подстановки — не ошибка». Это концепция и механизм, которые позволяют компилятору избежать ошибок компиляции при попытке подстановки шаблонов с некорректными типами аргументов. Вместо того чтобы считать такую ситуацию ошибкой и прекращать компиляцию, SFINAE позволяет компилятору просто исключить неподходящие специализации шаблона из рассмотрения.

Это достигается путем проверки, является ли выражение, связанное с подстановкой параметров шаблона, корректным в контексте, где происходит инстанцирование. Если выражение некорректно (например, вызывает ошибку компиляции), то компилятор просто пропускает данную специализацию шаблона и продолжает рассматривать другие альтернативы.

#для_продвинутых
std::mutex

std::mutex (мьютекс) — это часть стандартной библиотеки C++, предназначенная для обеспечения многопоточной синхронизации. Мьютексы используются для предотвращения одновременного доступа нескольких потоков к общему ресурсу, такому как переменная или участок кода, который должен выполняться атомарно (без прерывания другими потоками).

Однако следует быть осторожным при использовании мьютексов, так как неправильное управление ими может привести к проблемам с блокировкой и даже к взаимоблокировкам (deadlock).

#для_начинающих
Что такое явное приведение типов?

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

#для_начинающих
Сериализация

Сериализация — это процесс преобразования данных, таких как объекты, структуры или контейнеры, в последовательность байтов, чтобы их можно было сохранить или передать через сеть, а затем восстановить обратно в исходное состояние. Это позволяет сохранять состояние программы или обмениваться данными между разными программами или системами.

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

#для_продвинутых