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
Что такое struct?

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

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

#для_начинающих
Инициализация полей класса через конструкторы

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

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

#для_начинающих
Виртуальное наследование

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

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

#для_продвинутых
Имплементация

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

В C++ «имплементация» означает написание кода, который реализует методы, функции или классы, описанные в заголовочных файлах (header files). Заголовочные файлы содержат объявления (прототипы) функций и классов, а файлы с исходным кодом (.cpp) содержат реализацию этих функций и методов.

#для_начинающих
Позднее связывание

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

В C++ позднее связывание реализуется с помощью виртуальных функций и ключевого слова virtual. Виртуальные функции определяются в базовом классе и могут быть переопределены в производных классах. Когда вы вызываете виртуальную функцию через указатель или ссылку на базовый класс, вызывается соответствующая реализация в производном классе на основе реального типа объекта.

#для_продвинутых
Указатель на функцию

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

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

#для_начинающих
Ленивые вычисления

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

#для_продвинутых
inline-функции

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

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

#для_начинающих
std::make_shared

std::make_shared — это функция, определенная в заголовочном файле <memory>, которая используется для создания объектов в динамической памяти с использованием умных указателей std::shared_ptr.

Преимущество std::make_shared заключается в том, что она создает объект и управляющий блок (control block), содержащий метаинформацию и счетчик ссылок, в одном куске памяти. Это может улучшить производительность и уменьшить использование памяти по сравнению с созданием объекта и управляющего блока отдельно с использованием std::shared_ptr.

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

«rvalue» (сокращение от «right-hand value» или «что находится справа от оператора присваивания») — это выражение, которое может быть использовано только в правой части оператора присваивания или в контекстах, где ожидается значение, которое временно или по определению не может быть изменено. Rvalue не имеет имени или идентификатора, и после использования оно может быть уничтожено.

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

Return Value Optimization (RVO) - это оптимизация в C++, которая позволяет избежать лишних копирований объектов при возврате из функций. Она особенно полезна при возврате временных объектов или объектов, созданных внутри функции.

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

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

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

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

#для_продвинутых
Наследование

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

Существует два основных типа наследования: публичное и защищенное. Публичное наследование означает, что все общедоступные члены базового класса остаются общедоступными и в производном классе. Защищенное наследование делает общедоступные члены базового класса защищенными в производном классе. Также существует приватное наследование, которое делает общедоступные члены базового класса приватными в производном классе.

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

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

#для_продвинутых
Лямбда-функция

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

Лямбда-функции также часто используются вместе с алгоритмами стандартной библиотеки C++, такими как std::for_each, std::transform, std::sort (как на примере выше), и другими, чтобы создавать более компактный и выразительный код.

#для_начинающих
Семантика перемещения

Семантика перемещения позволяет эффективно перемещать ресурсы между объектами без копирования данных. Это понятие стало особенно актуальным в свете улучшений, внесенных в язык C++11 и последующих стандартах.

Семантика перемещения решает проблемы, связанные с копированием больших данных или ресурсов, что может быть очень затратным по времени и памяти. Вместо копирования данные «перемещаются» из одного объекта в другой, при этом исходный объект теряет право владения этими данными. Это осуществляется с использованием специальных методов и операторов, таких как конструктор перемещения (move constructor) и оператор перемещения (move assignment operator).
Виртуальные функции

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

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

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

Таким образом можно создать несколько вариантов функции, которые выполняют аналогичные действия, но принимают разные типы аргументов. Это позволяет создавать более удобный и интуитивно понятный интерфейс для программистов, так как они могут вызывать одно и то же имя функции с разными типами данных, не заботясь о различиях в именах функций.
Как работает std::unique_ptr?

std::unique_ptr — это умный указатель (smart pointer), предназначенный для управления динамически выделенными объектами. Он обеспечивает автоматическое освобождение памяти при выходе объекта из области видимости или при необходимости.

Принцип работы std::unique_ptr заключается в том, что он владеет указателем на выделенную память и следит за временем жизни этой памяти. Когда объект std::unique_ptr выходит из области видимости, он автоматически освобождает память, на которую он указывает, путем вызова оператора delete для хранящегося указателя.
Что такое memory leak?

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

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