Senior C++ Developer
13K subscribers
1.27K photos
3 videos
575 links
№ 4931128893
Изучаем C++.

По вопросам сотрудничества: @adv_and_pr
Download Telegram
Ключевое слово requires

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

В примере на картинке Sortable — это концепция, описывающая типы, для которых определены операторы сравнения («<» и «>»). Функция sortAndPrint принимает два аргумента типа T, удовлетворяющего концепции Sortable, и сравнивает их.

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

#для_начинающих
#вопросы_с_собеседований
В чем разница между git fetch и git pull?

Разница между этими командами заключается в том, что когда вы используете команду git fetch, Git извлекает последние изменения из удаленного репозитория в ваш локальный репозиторий, но оставляет эти изменения в отдельной ветке git origin.

А команда git pull извлекает и интегрирует (скачивает и сливает) последние изменения из удаленного репозитория в вашу текущую ветку работы.
Задача

Найти среднее арифметическое в трех рядах.

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

Теперь подумаем какие переменные нам понадобятся :

Переменная summa — для суммы чисел каждого ряда
Переменная average — для среднего арифметического каждого ряда
Переменная number — обычное число которое мы будем постоянно прибавлять
Переменные i и j — для циклов, перпенные у нас будут локальные, т.е. использоваться и объявляться и цикле.
Нейронные сети на Эльбрусе

Смотреть статью
Начало работы с Qt

Минимальный исходный код приложения Qt(часть 1).

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

Давайте скомпилируем это приложение. Нажав на зеленую стрелку в левом нижнем углу, Qt Creator скомпилирует и выполнит его.

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

Давайте добавим что-то для отображения(часть 2). Скомпилируйте его и… вот оно! Наше первое окно!
std::thread

std::thread является частью стандартной библиотеки C++ и предоставляет возможность создания и управления потоками выполнения.
Он позволяет запускать функции в отдельных потоках, обеспечивая параллельное выполнение кода.

Обратите внимание, что после создания потока std::thread, вы должны вызвать join() или detach() для корректной обработки завершения потока.

В приведенном примере мы использовали join(), чтобы основной поток дождался завершения потока t1. Если вы вызываете join() после завершения потока, программа может выдать исключение или вызвать неопределенное поведение.
#вопросы_с_собеседований
Предполагая, что buf является валидным указателем, в чем проблема в приведенном на картинке коде? Каким был бы альтернативный способ реализации этого, который позволил бы избежать этой проблемы?

Проблема в коде заключается в том, что --sz >= 0 всегда будет истинным, поэтому вы никогда не выйдете из цикла while (поэтому вы, вероятно, в конечном итоге испортите память или вызовете какое-то нарушение памяти или какой-либо другой программный сбой, в зависимости от того, что вы делаете внутри цикла). Причина, по которой --sz >= 0 всегда будет истинной, заключается в том, что тип sz равен size_t. size_t на самом деле просто псевдоним одного из основных беззнаковых целочисленных типов. Следовательно, поскольку sz не имеет знака, оно никогда не может быть меньше нуля (поэтому условие никогда не может быть ложным). Одним из примеров альтернативной реализации, позволяющей избежать этой проблемы, может быть использование цикла for следующим образом:
for (size_t i = 0; i < sz; i++)
Пример оконного приложения на C++ Qt

В программе окно создается на основе библиотечного класса QFrame. Этот класс является потомком класса QWidget. Так что можно без всяких проблем заменить в программе QFrame на QWidget.

Подробнее можно почитать здесь.
Что такое виртуальный деструктор и зачем он используется в C++?

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

Если виртуального деструктора не объявлено в базовом классе, то при удалении производного объекта через указатель на базовый класс будут вызываны только деструкторы базового класса, что может привести к утечкам памяти и неопределенному поведению.
This media is not supported in your browser
VIEW IN TELEGRAM
Волновой алгоритм

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

Смотреть статью
Поиск в ширину

Поиск в ширину (breadth-first search, BFS) - это алгоритм поиска или обхода графа. Он исследует все вершины на одном уровне, прежде чем переходить к следующему уровню.

Этот пример иллюстрирует обход в ширину для следующего графа:
0
/ \
1-----2
\
3
Начиная с вершины 2, алгоритм BFS посетит вершины в следующем порядке: 2, 0, 3, 1.
#вопросы_с_собеседований
Что делает данный код?

Правильный ответ: ничего не делает.

int main() // Функция main без аргументов.
{
[] // Объявление лямбда-функции без списка захвата...
() // ... с пустым списком аргументов ...
{} // ... и пустым телом, ...
(); // ... которая тут же вызывается.
}
std::make_shared

std::make_shared - это стандартная функция, используемая для создания объектов типа std::shared_ptr.
Она позволяет создавать объекты типа std::shared_ptr без использования оператора new. Это сокращает код и упрощает его читаемость.

В этом примере мы создаем класс MyClass, имеющий поле value и метод Print(), выводящий значение поля value на консоль. Затем мы используем std::make_shared для создания объекта типа std::shared_ptr:
std::make_shared<MyClass>(42);

*Обратите внимание, что таким способом созданный объект MyClass будет автоматически удален, когда на него не останется ссылок, даже если в вашем коде не указано delete.
Задача

В текстовом файле, содержащем текст программы на языке Си, проверить соответствие открывающихся и закрывающихся фигурных скобок { и }. Результат проверки вывести на экран и записать в виде фразы в текстовый файл. Результат работы программы (вывод) поместить в отдельный текстовый файл (например, "out . txt " ), продублировав на экране.
Программирование на С++ и URI в коде

Вы можете поместить URI в свой код на C++, и компилятор не выдаст ошибку. Любой идентификатор, за которым следует двоеточие, становится меткой goto в С++. Все, что следует за двойным слешем, воспринимается как комментарий. Именно поэтому в приведенном выше коде http – это метка, а //google.com/ – комментарий. Но компилятор может выдать предупреждение, так как заданная метка не используется.
Основные концепции библиотеки chrono (C++)

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

Для избежания таких ошибок предусмотрена библиотека chrono (namespace std::chrono). Она была добавлена в C++11 и дорабатывалась в поздних стандартах.

Смотреть статью
#вопросы_с_собеседований
Бывает такое, что оператор new не выделяет память?

Ответ:
Да, бывает, когда new передаётся указатель на уже выделенную память (например, с помощью malloc). Это называется placement new. И оператор new без изменения возвращает второй параметр - указатель (void* operator new(std::size_t, void*)). Это используется для создания объектов в выделенном "хранилище" или после malloc.

Важно! В этом случае деструктор нужно вызывать самостоятельно!
Функция resize

Изменяет размер контейнера так, чтобы он содержал n элементов.

Если n меньше текущего размера контейнера , содержимое сокращается до первых n элементов, удаляя все остальные (и уничтожая их).

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

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