uz
Feedback
C/C++ | Вопросы собесов

C/C++ | Вопросы собесов

Kanalga Telegram’da o‘tish

Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv

Ko'proq ko'rsatish
4 195
Obunachilar
-124 soatlar
+57 kun
+1630 kun
Obunachilarni jalb qilish
Sentabr '26
Sentabr '26
+39
0 kanalda
Avgust '26
+40
0 kanalda
Get PRO
Iyul '26
+54
0 kanalda
Get PRO
Iyun '26
+46
1 kanalda
Get PRO
May '26
+54
0 kanalda
Get PRO
Aprel '26
+43
0 kanalda
Get PRO
Mart '26
+58
0 kanalda
Get PRO
Fevral '26
+69
0 kanalda
Get PRO
Yanvar '26
+84
0 kanalda
Get PRO
Dekabr '25
+42
0 kanalda
Get PRO
Noyabr '25
+100
0 kanalda
Get PRO
Oktabr '25
+54
0 kanalda
Get PRO
Sentabr '25
+47
0 kanalda
Get PRO
Avgust '25
+77
0 kanalda
Get PRO
Iyul '25
+72
0 kanalda
Get PRO
Iyun '25
+83
0 kanalda
Get PRO
May '25
+83
0 kanalda
Get PRO
Aprel '25
+99
3 kanalda
Get PRO
Mart '25
+88
2 kanalda
Get PRO
Fevral '25
+187
3 kanalda
Get PRO
Yanvar '25
+129
53 kanalda
Get PRO
Dekabr '24
+148
0 kanalda
Get PRO
Noyabr '24
+123
0 kanalda
Get PRO
Oktabr '24
+448
43 kanalda
Get PRO
Sentabr '24
+643
252 kanalda
Get PRO
Avgust '24
+127
0 kanalda
Get PRO
Iyul '24
+191
54 kanalda
Get PRO
Iyun '24
+1 110
244 kanalda
Get PRO
May '24
+1 483
192 kanalda
Get PRO
Aprel '24
+706
22 kanalda
Sana
Obunachilarni jalb qilish
Esdaliklar
Kanallar
15 Sentabr+2
14 Sentabr+5
13 Sentabr0
12 Sentabr+2
11 Sentabr+4
10 Sentabr+4
09 Sentabr+2
08 Sentabr+5
07 Sentabr+1
06 Sentabr+5
05 Sentabr+1
04 Sentabr+1
03 Sentabr+3
02 Sentabr+4
01 Sentabr0
Kanal postlari
🤔 Что знаешь о умных указателях? Умные указатели (smart pointers) в C++ – это классы-обёртки для обычных указателей, которые автоматически управляют временем жизни объектов в динамической памяти. Они помогают избежать утечек памяти и делают код более безопасным, минимизируя вероятность ошибок с указателями. 🚩Зачем нужны умные указатели? 🟠Управление ресурсами Автоматически освобождают память, когда объект больше не нужен. 🟠Исключение утечек памяти С их помощью можно избежать забывания вызова delete. 🟠Улучшение безопасности Умные указатели предотвращают доступ к освобождённой памяти (dangling pointers). 🟠Снижение сложности RAII (Resource Acquisition Is Initialization) позволяет делегировать управление ресурсами объектам. 🚩Типы умных указателей 🟠`std::unique_ptr` Уникальный указатель (unique pointer) обладает единственным владельцем объекта. После передачи владения объектом другому std::unique_ptr, исходный указатель становится недействительным. Обеспечивает строгую семантику владения. Лёгкий, так как не использует счётчики ссылок. Не копируемый, но перемещаемый.
#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "Создан объект\n"; }
    ~MyClass() { std::cout << "Удалён объект\n"; }
};

int main() {
    std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); // Владеет объектом
    std::unique_ptr<MyClass> ptr2 = std::move(ptr1);            // Передача владения
    // ptr1 теперь nullptr, ptr2 владеет объектом
    return 0; // Объект автоматически удаляется
}
🟠`std::shared_ptr` Разделяемый указатель (shared pointer) поддерживает разделённое владение объектом. Указатель освобождает память только тогда, когда все std::shared_ptr, ссылающиеся на объект, будут уничтожены. Использует счётчик ссылок (reference count). Обеспечивает совместное использование ресурса несколькими владельцами.
#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "Создан объект\n"; }
    ~MyClass() { std::cout << "Удалён объект\n"; }
};

int main() {
    std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
    std::shared_ptr<MyClass> ptr2 = ptr1; // Разделение владения
    // Указатель ptr1 и ptr2 указывают на один и тот же объект
    return 0; // Объект удаляется после уничтожения последнего shared_ptr
}
🟠`std::weak_ptr` Слабый указатель (weak pointer) не увеличивает счётчик ссылок. Используется для предотвращения циклических зависимостей между std::shared_ptr. Ссылается на объект, которым управляет std::shared_ptr. Не владеет объектом. Может проверять существование объекта с помощью expired().
#include <iostream>
#include <memory>

class MyClass {
public:
    MyClass() { std::cout << "Создан объект\n"; }
    ~MyClass() { std::cout << "Удалён объект\n"; }
};

int main() {
    std::shared_ptr<MyClass> shared = std::make_shared<MyClass>();
    std::weak_ptr<MyClass> weak = shared; // Слабая ссылка
    if (auto ptr = weak.lock()) { // Проверка на существование
        std::cout << "Объект существует\n";
    }
    shared.reset(); // Освобождаем shared_ptr
    if (weak.expired()) {
        std::cout << "Объект удалён\n";
    }
    return 0;
}
Ставь 👍 и забирай 📚 Базу знаний

2
Недорогие VPS-серверы от NetAngels Подберем мощные VDS-сервер для любых задач. Техподдержка 24/7. Защита от DDoS-атак. Гибкая
Недорогие VPS-серверы от NetAngels Подберем мощные VDS-сервер для любых задач. Техподдержка 24/7. Защита от DDoS-атак. Гибкая конфигурация. Бесплатный перенос VDS с сохранением всех данных. Попробуйте VDS-сервер от NetAngels уже сегодня! Перейти на сайт #реклама 16+ netangels.ru О рекламодателе
240
3
🤔 Как сделать так, чтобы в shared_ptr были утечки? Утечки возможны при создании циклических ссылок, например, когда два объекта хранят shared_ptr друг на друга. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний
298
4
🤔 Что будет если сделать delete для nullptr? В C++ delete nullptr безопасен и не делает ничего. Стандарт гарантирует, что delete не вызывает ошибок при передаче nullptr. int* p = nullptr; delete p; // НИЧЕГО НЕ ПРОИЗОЙДЁТ (без ошибки) 🚩Почему `delete nullptr` не вызывает ошибку? Стандарт C++ (C++98, C++11, C++17, C++20) говорит: > Если переданный в delete указатель равен nullptr, то delete ничего не делает. Это сделано, чтобы избежать избыточных проверок в коде: if (ptr) { // Проверка не нужна delete ptr; } 🚩Как работает `delete` внутри? Когда вызывается delete p, компилятор: Проверяет, равен ли p nullptr. Если да → ничего не делает. Вызывает деструктор объекта, если p не nullptr. Освобождает память с помощью operator delete(). 🚩Что с `delete[]`? Тоже безопасно int* arr = nullptr; delete[] arr; // НИЧЕГО НЕ ПРОИЗОЙДЁТ 🚩Ошибки, которых `delete nullptr` помогает избежать Безопасно void destroy(int* p) { delete p; // Даже если p == nullptr, ошибки не будет } Опасность: двойное удаление Хотя delete nullptr безопасен, удаление уже освобождённого указателя — ошибка! int* p = new int(10); delete p; // Освободили память delete p; // ❌ НЕСКОЛЬКО DELETE - неопределённое поведение (UB)! Решение: после delete занулять указатель int* p = new int(10); delete p; p = nullptr; // Теперь повторный delete безопасен delete p; // ОК, ничего не делает Ставь 👍 и забирай 📚 Базу знаний
335
5
Создание кроссплатформенного GUI на Rust ⚡Electron тяжёл, а Rust + Tauri дают лёгкое, быстрое и безопасное десктоп-приложение
Создание кроссплатформенного GUI на Rust ⚡Electron тяжёл, а Rust + Tauri дают лёгкое, быстрое и безопасное десктоп-приложение для Windows, macOS и Linux. Tauri берёт HTML/CSS/JS для интерфейса и мощь Rust для бэкенда. 📅 23 сентября в 20:00 на открытом вебинаре разберём полный цикл создания GUI на Rust с Tauri: организация проекта, логика на Rust и её связь с интерфейсом, работа с данными, безопасные системные вызовы через permissions и capabilities в Tauri 2, асинхронность, сборка, отладка и лучшие практики. 💻 Вебинар не для тех, кто ждёт «скопируй-вставь». Подойдёт фронтенд-разработчикам, программистам, интересующимся Rust, и энтузиастам, уставшим от Electron. ✅ После вебинара вы сможете создавать десктоп-приложения на Rust, связывать логику с UI, настраивать безопасность и собирать готовое приложение. Записаться #реклама 16+ otus.ru О рекламодателе
331
6
🤔 Чем отличаются STL-контейнеры vector и array? 1. vector: - Динамический массив, размер которого можно изменять. - Управляет памятью автоматически. - Подходит для сценариев, где размер данных неизвестен заранее. 2. array: - Статический массив, размер которого фиксирован при создании. - Не выделяет и не освобождает память динамически. - Быстрее и эффективнее для небольших данных с фиксированным размером. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний
337
7
🤔 Как пофиксить проблему, когда mutex является локальной переменной? Использование std::mutex в качестве локальной переменной может привести к различным проблемам, особенно если он используется для синхронизации доступа к общим данным. Локальный std::mutex будет уничтожен при выходе из области видимости, что нарушит работу других потоков, ожидающих блокировку или разблокировку. 🚩Проблемы с локальным `std::mutex` 🟠Жизненный цикл локального `std::mutex` Локальная переменная уничтожается при выходе из функции или блока, в котором она объявлена. Это может привести к неопределенному поведению, если другие потоки все еще используют этот мьютекс. 🟠Неопределенное поведение Уничтожение мьютекса, который все еще заблокирован, может привести к неопределенному поведению программы и потенциальным сбоям. 🚩Решение проблемы Чтобы исправить проблему, нужно гарантировать, что std::mutex имеет более длительный срок жизни и доступен всем потокам, которые его используют. 🚩Правильные подходы 🟠Использование глобального или статического мьютекса Если мьютекс используется для защиты глобальных или статических данных, сделайте его также глобальным или статическим. #include <iostream> #include <thread> #include <mutex> std::mutex mtx; void sharedFunction() { std::lock_guard<std::mutex> lock(mtx); // Доступ к общим данным std::cout << "Thread " << std::this_thread::get_id() << " is running\n"; } int main() { std::thread t1(sharedFunction); std::thread t2(sharedFunction); t1.join(); t2.join(); return 0; } 🟠Член класса Если мьютекс используется для защиты данных объекта, объявите его членом класса. #include <iostream> #include <thread> #include <mutex> class SharedResource { private: std::mutex mtx; int data; public: void increment() { std::lock_guard<std::mutex> lock(mtx); ++data; std::cout << "Data: " << data << " from thread " << std::this_thread::get_id() << "\n"; } }; int main() { SharedResource resource; std::thread t1(&SharedResource::increment, &resource); std::thread t2(&SharedResource::increment, &resource); t1.join(); t2.join(); return 0; } 🟠Использование умных указателей Если мьютекс должен иметь динамическую продолжительность жизни, используйте умные указатели, такие как std::shared_ptr или std::unique_ptr. #include <iostream> #include <thread> #include <mutex> #include <memory> void sharedFunction(std::shared_ptr<std::mutex> mtx) { std::lock_guard<std::mutex> lock(*mtx); // Доступ к общим данным std::cout << "Thread " << std::this_thread::get_id() << " is running\n"; } int main() { auto mtx = std::make_shared<std::mutex>(); std::thread t1(sharedFunction, mtx); std::thread t2(sharedFunction, mtx); t1.join(); t2.join(); return 0; } Ставь 👍 и забирай 📚 Базу знаний
296
8
Проводим розыгрыш в нашем боте 20 Яндекс Станций, 5 пар Яндекс Дропс и крутой мерч, который будет помогать создавать новое уж
Проводим розыгрыш в нашем боте 20 Яндекс Станций, 5 пар Яндекс Дропс и крутой мерч, который будет помогать создавать новое уже сегодня! Узнать больше #реклама 16+ refer.id О рекламодателе
339
9
🤔 Что будет, если для беззнаковой переменной, равной 0, сделать декремент? Значение переменной перейдёт в максимальное значение типа (например, UINT_MAX для unsigned int). Это связано с переполнением, так как беззнаковые типы используют арифметику по модулю. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний
359
10
🤔 Чем отличаются STL контейнеры vector и array? Это контейнеры из стандартной библиотеки, но у них есть важные различия в управлении памятью, гибкости и производительности. 🟠Различия в управлении памятью std::vector использует динамическую память, выделяемую в куче (heap). Его размер может изменяться во время выполнения. std::array использует статическую память, выделяемую в стеке (stack) или в статической области памяти, и его размер фиксирован на этапе компиляции. #include <vector> #include <array> #include <iostream> int main() { std::vector<int> vec = {1, 2, 3}; // Размер может изменяться динамически vec.push_back(4); // Добавляем новый элемент std::array<int, 3> arr = {1, 2, 3}; // Размер фиксирован, нельзя добавить новый элемент std::cout << "Vector size: " << vec.size() << std::endl; // Выведет 4 std::cout << "Array size: " << arr.size() << std::endl; // Выведет 3 return 0; } 🟠Гибкость и изменение размера std::vector позволяет изменять размер в процессе работы, автоматически выделяя новую память при необходимости. std::array имеет фиксированный размер, который нельзя изменить после создания. std::vector<int> v = {1, 2, 3}; v.push_back(4); // Увеличиваем размер std::array<int, 3> a = {1, 2, 3}; // a.push_back(4); // Ошибка! У std::array нет метода push_back 🟠Производительность std::array работает быстрее, так как все данные хранятся в непрерывном участке памяти и нет затрат на динамическое выделение. std::vector может требовать дополнительное время при изменении размера, так как может потребоваться новое выделение памяти и копирование элементов. #include <vector> #include <array> #include <chrono> #include <iostream> int main() { constexpr int N = 1'000'000; std::vector<int> vec(N, 1); // Динамический массив std::array<int, N> arr{}; // Статический массив auto start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < N; ++i) vec[i] += 1; auto end = std::chrono::high_resolution_clock::now(); std::cout << "Vector time: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << " us" << std::endl; start = std::chrono::high_resolution_clock::now(); for (int i = 0; i < N; ++i) arr[i] += 1; end = std::chrono::high_resolution_clock::now(); std::cout << "Array time: " << std::chrono::duration_cast<std::chrono::microseconds>(end - start).count() << " us" << std::endl; return 0; } 🟠Совместимость с C-API std::array хранит данные как обычный C-массив, поэтому можно легко передавать его в функции, ожидающие int*. std::vector использует динамическую память, но можно получить указатель на внутренний буфер с помощью data(). void processArray(int* arr, size_t size) { for (size_t i = 0; i < size; ++i) { std::cout << arr[i] << " "; } } int main() { std::array<int, 3> arr = {1, 2, 3}; std::vector<int> vec = {4, 5, 6}; processArray(arr.data(), arr.size()); // std::array можно передавать в C-функции processArray(vec.data(), vec.size()); // std::vector тоже можно передавать return 0; } 🟠Итераторы и стандартные алгоритмы Оба контейнера поддерживают итераторы и совместимы со стандартными алгоритмами из #include <algorithm> #include <iostream> #include <vector> #include <array> #include <algorithm> int main() { std::vector<int> vec = {3, 1, 4, 1, 5}; std::array<int, 5> arr = {3, 1, 4, 1, 5}; std::sort(vec.begin(), vec.end()); std::sort(arr.begin(), arr.end()); for (int n : vec) std::cout << n << " "; // 1 1 3 4 5 std::cout << std::endl; for (int n : arr) std::cout << n << " "; // 1 1 3 4 5 return 0; } Ставь 👍 и забирай 📚 Базу знаний
305
11
🤔 Сложность поиска в бинарных деревьях логарифмическая, всегда ли так? Нет, сложность поиска в бинарных деревьях не всегда логарифмическая. Она зависит от структуры дерева. Хотя логарифмическая сложность \(O(\log N)\) считается идеальной, это справедливо только для сбалансированных бинарных деревьев. Давайте разберём, когда эта сложность сохраняется, а когда может увеличиваться. 🚩Идеальный случай: сбалансированное бинарное дерево Если бинарное дерево поиска (Binary Search Tree, BST) сбалансировано, глубина дерева пропорциональна \( \log_2 N \), где \(N\) – количество узлов. В этом случае поиск, вставка и удаление элемента выполняются за \(O(\log N)\). 🚩Худший случай: несбалансированное дерево Если дерево несбалансировано, то оно может выродиться в связный список, где каждый узел имеет только одного потомка (левого или правого). 🚩Как избежать вырождения дерева? Чтобы поддерживать сложность операций \(O(\log N)\), используют сбалансированные бинарные деревья, такие как: 🟠AVL-деревья Поддерживают балансировку после каждой операции вставки/удаления. 🟠Красно-чёрные деревья Гарантируют, что глубина дерева остаётся \(O(\log N)\). 🟠B-деревья и B+ деревья Используются для работы с большими объёмами данных, например, в базах данных. Ставь 👍 и забирай 📚 Базу знаний
355
12
🤔 Может ли быть проблема со вставкой ста элементов через push_back? Проблема может возникнуть, если память vector переполнена, что требует перераспределения и копирования всех существующих элементов в новый массив, увеличивая временные затраты. Для большого количества вставок рекомендуется заранее вызвать reserve, чтобы выделить необходимую память и избежать перераспределений. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний
363
13
Персональный подарок тому, кто ведёт блог о своей жизни Выкачаем посты с фото и текстами и напечатаем книгу. Можно печатать с
Персональный подарок тому, кто ведёт блог о своей жизни Выкачаем посты с фото и текстами и напечатаем книгу. Можно печатать свой профиль, а можно чей-то ещё (чтобы сделать прекрасный подарок). Работаем с разными соцсетями, где бывают картинки с текстами под ними. Книга формата А5, от 100 до 1000 страниц. Цена от 7 до 24 тыс. руб. Перейти на сайт #реклама intro.blogbuk.ru О рекламодателе
299
14
🤔 Какие есть виды полиморфизма? В программировании, включая C++, полиморфизм (многоформенность) – это способность объекта или функции принимать разные формы. Полиморфизм является ключевой концепцией объектно-ориентированного программирования (ООП). 🚩Компиляторный (статический) полиморфизм Этот вид полиморфизма реализуется во время компиляции. Он достигается с помощью перегрузки функций (function overloading) и перегрузки операторов (operator overloading). 🟠Перегрузка функций В перегрузке функций одна функция имеет несколько определений с разными параметрами. #include <iostream> void print(int value) { std::cout << "Целое число: " << value << std::endl; } void print(double value) { std::cout << "Вещественное число: " << value << std::endl; } void print(const std::string& value) { std::cout << "Строка: " << value << std::endl; } int main() { print(42); // Вызов функции для int print(3.14); // Вызов функции для double print("Привет!"); // Вызов функции для строки return 0; } 🟠Перегрузка операторов Перегрузка операторов позволяет определить, как стандартные операторы работают с пользовательскими типами данных. #include <iostream> class Complex { double real, imag; public: Complex(double r, double i) : real(r), imag(i) {} Complex operator+(const Complex& other) const { return Complex(real + other.real, imag + other.imag); } void display() const { std::cout << real << " + " << imag << "i" << std::endl; } }; int main() { Complex c1(1.0, 2.0), c2(3.0, 4.0); Complex c3 = c1 + c2; // Используется перегрузка оператора + c3.display(); // Вывод: 4 + 6i return 0; } 🚩Рантаймный (динамический) полиморфизм Этот вид полиморфизма проявляется во время выполнения программы. Реализуется с использованием виртуальных функций и наследования. Виртуальные функции #include <iostream> class Animal { public: virtual void sound() const { // Виртуальная функция std::cout << "Некоторый звук" << std::endl; } }; class Dog : public Animal { public: void sound() const override { // Переопределение std::cout << "Гав-гав" << std::endl; } }; class Cat : public Animal { public: void sound() const override { // Переопределение std::cout << "Мяу" << std::endl; } }; void makeSound(const Animal& animal) { animal.sound(); // Динамическое определение, какой sound() вызывать } int main() { Dog dog; Cat cat; makeSound(dog); // Вывод: Гав-гав makeSound(cat); // Вывод: Мяу return 0; } Ставь 👍 и забирай 📚 Базу знаний
327
15
Долгожданный Solaris KRS в кредит на выгодных условиях Автозапуск и заводская телематика. Цифровой автомобиль. Оставьте заявк
Долгожданный Solaris KRS в кредит на выгодных условиях Автозапуск и заводская телематика. Цифровой автомобиль. Оставьте заявку! Узнать больше Изучите все условия кредита (займа) на сайте в соответствующем разделе. Оценивайте свои финансовые возможности и риски. Финансовые услуги оказывает: ПАО "Совкомбанк", СПАО "Ингосстрах" и другие. #реклама mrqz.me О рекламодателе
314
16
🤔 Что пришло на смену auto_ptr? На смену auto_ptr пришли умные указатели unique_ptr и shared_ptr. unique_ptr безопаснее управляет памятью и исключает случайное копирование, что было проблемой в auto_ptr. Эти новые указатели входят в стандарт C++11 и являются более надежными. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний
440
17
🤔 Каким свойством должен обладать объект, чтобы его можно было добавить в ассоциативные контейнеры в качестве ключа? Чтобы объект можно было использовать в качестве ключа в ассоциативных контейнерах (std::set, std::map, std::unordered_set, std::unordered_map), он должен обладать определёнными свойствами, которые зависят от типа контейнера. 🚩Требования к объекту-ключу 🟠Для `std::map` и `std::set` (красно-чёрное дерево) Класс или структура, используемая в качестве ключа, должна поддерживать операцию < (меньше). #include <iostream> #include <map> struct Person { std::string name; int age; // Оператор сравнения, необходимый для std::map и std::set bool operator<(const Person& other) const { return age < other.age; // Ключи будут упорядочены по возрасту } }; int main() { std::map<Person, std::string> people; people[{ "Alice", 30 }] = "Doctor"; people[{ "Bob", 25 }] = "Engineer"; for (const auto& [key, value] : people) { std::cout << key.name << " (" << key.age << "): " << value << '\n'; } } 🟠Для `std::unordered_map` и `std::unordered_set` (хеш-таблица) Объект-ключ должен поддерживать операции: Оператор == (для проверки равенства) Функция-хешер (по умолчанию std::hash<T>) #include <iostream> #include <unordered_map> struct Person { std::string name; int age; // Оператор равенства нужен для сравнения ключей bool operator==(const Person& other) const { return name == other.name && age == other.age; } }; // Специализация std::hash для структуры Person namespace std { template <> struct hash<Person> { std::size_t operator()(const Person& p) const { return std::hash<std::string>()(p.name) ^ (std::hash<int>()(p.age) << 1); } }; } int main() { std::unordered_map<Person, std::string> people; people[{ "Alice", 30 }] = "Doctor"; people[{ "Bob", 25 }] = "Engineer"; for (const auto& [key, value] : people) { std::cout << key.name << " (" << key.age << "): " << value << '\n'; } } Ставь 👍 и забирай 📚 Базу знаний
487
18
Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп от 3-5 тыс. рублей в день. Без опыта, нужен
Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп от 3-5 тыс. рублей в день. Без опыта, нужен только телефон, занятость 3-6 часов в день. Всему обучат на бесплатном курсе и после возьму на работу. Как проходят уроки: ✅ 3 дня уроков по 30 минут ✅ Домашки с проверкой и оплатой бонусами ✅ Плачу 10 тыс за каждую выполненную домашку Все кто пройдет курс, получат сертификат от школы с образовательной лицензией. ⚡ Места ограничены. Набор может закрыться в любой момент. 👍 Жмите "Зарегистрироваться", чтобы успеть занять место. Зарегистрироваться #реклама 16+ course.wildcard.ru О рекламодателе
326
19
🤔 Зачем нам нужна move семантика? Move семантика введена с целью повышения эффективности работы с ресурсами, такими как память, файлы, сокеты и другие объекты, которые занимают значительные ресурсы. Она позволяет избежать ненужного копирования объектов, что может быть дорогостоящим как по времени, так и по памяти. 🚩Зачем она нужна? 🟠Эффективность работы с ресурсами Копирование больших объектов может быть очень затратным. Move семантика позволяет перенести ресурсы от одного объекта к другому без дорогостоящего копирования. 🟠Улучшение производительности Перемещение (move) быстрее копирования, поскольку оно всего лишь переназначает указатели на ресурсы, вместо создания их копий. Это особенно важно в приложениях с высокой производительностью, таких как игры, обработка видео, базы данных. 🚩Как это используется? Move семантика реализуется с помощью rvalue ссылок (ссылок на временные объекты) и специальных методов — move конструктора и move оператора присваивания. #include <iostream> #include <vector> class MyClass { public: int* data; size_t size; // Конструктор MyClass(size_t s) : size(s), data(new int[s]) { std::cout << "Constructing MyClass\n"; } // Деструктор ~MyClass() { delete[] data; std::cout << "Destructing MyClass\n"; } // Move конструктор MyClass(MyClass&& other) noexcept : data(other.data), size(other.size) { other.data = nullptr; // Обнуляем указатель у "старого" объекта other.size = 0; std::cout << "Move constructing MyClass\n"; } // Move оператор присваивания MyClass& operator=(MyClass&& other) noexcept { if (this != &other) { delete[] data; // Освобождаем старый ресурс data = other.data; size = other.size; other.data = nullptr; // Обнуляем указатель у "старого" объекта other.size = 0; std::cout << "Move assigning MyClass\n"; } return *this; } }; int main() { MyClass a(10); // Создаем объект a MyClass b = std::move(a); // Перемещаем ресурсы от a к b return 0; } Ставь 👍 и забирай 📚 Базу знаний
466
20
IT-инфраструктура под ключ с поддержкой Yandex Cloud Спроектируем, запустим и возьмём на сопровождение. Экспертиза целой кома+4
IT-инфраструктура под ключ с поддержкой Yandex Cloud Спроектируем, запустим и возьмём на сопровождение. Экспертиза целой команды без найма в штат. 💰Новым клиентам — грант на облачные сервисы, платите только за работу специалистов. Оставьте заявку на сайте: подберём партнёра и рассчитаем стоимость. Получить консультацию #реклама 16+ yandex.cloud О рекламодателе
298