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

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

前往频道在 Telegram

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

显示更多
4 195
订阅者
-124 小时
+57 天
+1630 天
帖子存档
🤔 Что знаешь о умных указателях? Умные указатели (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;
}
Ставь 👍 и забирай 📚 Базу знаний

Недорогие VPS-серверы от NetAngels Подберем мощные VDS-сервер для любых задач. Техподдержка 24/7. Защита от DDoS-атак. Гибкая
Недорогие VPS-серверы от NetAngels Подберем мощные VDS-сервер для любых задач. Техподдержка 24/7. Защита от DDoS-атак. Гибкая конфигурация. Бесплатный перенос VDS с сохранением всех данных. Попробуйте VDS-сервер от NetAngels уже сегодня! Перейти на сайт #реклама 16+ netangels.ru О рекламодателе

🤔 Как сделать так, чтобы в shared_ptr были утечки? Утечки возможны при создании циклических ссылок, например, когда два объекта хранят shared_ptr друг на друга. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

🤔 Что будет если сделать 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; // ОК, ничего не делает
Ставь 👍 и забирай 📚 Базу знаний

Создание кроссплатформенного 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 О рекламодателе

🤔 Чем отличаются STL-контейнеры vector и array? 1. vector: - Динамический массив, размер которого можно изменять. - Управляет памятью автоматически. - Подходит для сценариев, где размер данных неизвестен заранее. 2. array: - Статический массив, размер которого фиксирован при создании. - Не выделяет и не освобождает память динамически. - Быстрее и эффективнее для небольших данных с фиксированным размером. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

🤔 Как пофиксить проблему, когда 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;
}
Ставь 👍 и забирай 📚 Базу знаний

Проводим розыгрыш в нашем боте 20 Яндекс Станций, 5 пар Яндекс Дропс и крутой мерч, который будет помогать создавать новое уж
Проводим розыгрыш в нашем боте 20 Яндекс Станций, 5 пар Яндекс Дропс и крутой мерч, который будет помогать создавать новое уже сегодня! Узнать больше #реклама 16+ refer.id О рекламодателе

🤔 Что будет, если для беззнаковой переменной, равной 0, сделать декремент? Значение переменной перейдёт в максимальное значение типа (например, UINT_MAX для unsigned int). Это связано с переполнением, так как беззнаковые типы используют арифметику по модулю. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

🤔 Чем отличаются 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;
}
Ставь 👍 и забирай 📚 Базу знаний

🤔 Сложность поиска в бинарных деревьях логарифмическая, всегда ли так? Нет, сложность поиска в бинарных деревьях не всегда логарифмическая. Она зависит от структуры дерева. Хотя логарифмическая сложность \(O(\log N)\) считается идеальной, это справедливо только для сбалансированных бинарных деревьев. Давайте разберём, когда эта сложность сохраняется, а когда может увеличиваться. 🚩Идеальный случай: сбалансированное бинарное дерево Если бинарное дерево поиска (Binary Search Tree, BST) сбалансировано, глубина дерева пропорциональна \( \log_2 N \), где \(N\) – количество узлов. В этом случае поиск, вставка и удаление элемента выполняются за \(O(\log N)\). 🚩Худший случай: несбалансированное дерево Если дерево несбалансировано, то оно может выродиться в связный список, где каждый узел имеет только одного потомка (левого или правого). 🚩Как избежать вырождения дерева? Чтобы поддерживать сложность операций \(O(\log N)\), используют сбалансированные бинарные деревья, такие как: 🟠AVL-деревья Поддерживают балансировку после каждой операции вставки/удаления. 🟠Красно-чёрные деревья Гарантируют, что глубина дерева остаётся \(O(\log N)\). 🟠B-деревья и B+ деревья Используются для работы с большими объёмами данных, например, в базах данных. Ставь 👍 и забирай 📚 Базу знаний

🤔 Может ли быть проблема со вставкой ста элементов через push_back? Проблема может возникнуть, если память vector переполнена, что требует перераспределения и копирования всех существующих элементов в новый массив, увеличивая временные затраты. Для большого количества вставок рекомендуется заранее вызвать reserve, чтобы выделить необходимую память и избежать перераспределений. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

Персональный подарок тому, кто ведёт блог о своей жизни Выкачаем посты с фото и текстами и напечатаем книгу. Можно печатать свой профиль, а можно чей-то ещё (чтобы сделать прекрасный подарок). Работаем с разными соцсетями, где бывают картинки с текстами под ними. Книга формата А5, от 100 до 1000 страниц. Цена от 7 до 24 тыс. руб. Перейти на сайт #реклама intro.blogbuk.ru О рекламодателе

🤔 Какие есть виды полиморфизма? В программировании, включая 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;
}
Ставь 👍 и забирай 📚 Базу знаний

Долгожданный Solaris KRS в кредит на выгодных условиях Автозапуск и заводская телематика. Цифровой автомобиль. Оставьте заявк
Долгожданный Solaris KRS в кредит на выгодных условиях Автозапуск и заводская телематика. Цифровой автомобиль. Оставьте заявку! Узнать больше Изучите все условия кредита (займа) на сайте в соответствующем разделе. Оценивайте свои финансовые возможности и риски. Финансовые услуги оказывает: ПАО "Совкомбанк", СПАО "Ингосстрах" и другие. #реклама mrqz.me О рекламодателе

🤔 Что пришло на смену auto_ptr? На смену auto_ptr пришли умные указатели unique_ptr и shared_ptr. unique_ptr безопаснее управляет памятью и исключает случайное копирование, что было проблемой в auto_ptr. Эти новые указатели входят в стандарт C++11 и являются более надежными. Ставь 👍 если знал ответ, 🔥 если нет Забирай 📚Базу знаний

🤔 Каким свойством должен обладать объект, чтобы его можно было добавить в ассоциативные контейнеры в качестве ключа? Чтобы объект можно было использовать в качестве ключа в ассоциативных контейнерах (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';
    }
}
Ставь 👍 и забирай 📚 Базу знаний

Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп от 3-5 тыс. рублей в день. Без опыта, нужен
Ищу желающих заполнять карточки товаров на ВБ! Работа полностью на удаленке с зп от 3-5 тыс. рублей в день. Без опыта, нужен только телефон, занятость 3-6 часов в день. Всему обучат на бесплатном курсе и после возьму на работу. Как проходят уроки: ✅ 3 дня уроков по 30 минут ✅ Домашки с проверкой и оплатой бонусами ✅ Плачу 10 тыс за каждую выполненную домашку Все кто пройдет курс, получат сертификат от школы с образовательной лицензией. ⚡ Места ограничены. Набор может закрыться в любой момент. 👍 Жмите "Зарегистрироваться", чтобы успеть занять место. Зарегистрироваться #реклама 16+ course.wildcard.ru О рекламодателе

🤔 Зачем нам нужна 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;
}
Ставь 👍 и забирай 📚 Базу знаний

IT-инфраструктура под ключ с поддержкой Yandex Cloud Спроектируем, запустим и возьмём на сопровождение. Экспертиза целой кома
+4
IT-инфраструктура под ключ с поддержкой Yandex Cloud Спроектируем, запустим и возьмём на сопровождение. Экспертиза целой команды без найма в штат. 💰Новым клиентам — грант на облачные сервисы, платите только за работу специалистов. Оставьте заявку на сайте: подберём партнёра и рассчитаем стоимость. Получить консультацию #реклама 16+ yandex.cloud О рекламодателе