Назад к вопросам
Middle
132
questionbank

Для чего в умных указателях используются делеторы?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Делеторы в умных указателях (например, std::unique_ptr, std::shared_ptr) используются для определения пользовательской функции или объекта, который будет вызван для освобождения ресурса, управляемого указателем, вместо стандартного оператора delete.

Типичные случаи использования:

  • Управление не-Heap ресурсами: Освобождение ресурсов, выделенных не с помощью new (например, файлы с помощью fclose, хэндлы WinAPI, ресурсы в памяти с использованием malloc и free).
  • Ресурсы с пользовательским освобождением: Когда требуется выполнить дополнительные действия перед освобождением памяти или использовать специфические функции освобождения для определенных объектов.
  • Интероперабельность с C API: Работа с указателями, полученными из библиотек C, где освобождение ресурса требует вызова определенной функции.

Пример с std::unique_ptr:

#include <cstdio> // Для функций fopen и fclose
#include <memory> // Для unique_ptr
#include <iostream>

// Пользовательский делетор для FILE*
struct FileCloser {
    void operator()(FILE* file) const {
        if (file) {
            std::cout << "Closing file." << std::endl;
            fclose(file);
        }
    }
};

int main() {
    // Создание unique_ptr с пользовательским делетором
    std::unique_ptr<FILE, FileCloser> file_ptr(fopen("example.txt", "w"));

    if (file_ptr) {
        fputs("Hello, world!\n", file_ptr.get());
    } else {
        std::cerr << "Failed to open file." << std::endl;
    }

    // Файл будет закрыт автоматически при выходе из области видимости main
    // благодаря вызову делетора FileCloser::operator()
    return 0;
}

Пример с std::shared_ptr:

#include <memory> // Для shared_ptr
#include <iostream>

struct MyResource {
    MyResource() { std::cout << "MyResource created." << std::endl; }
    ~MyResource() { std::cout << "MyResource destroyed." << std::endl; }
};

// Пользовательский делетор
void custom_deleter(MyResource* ptr) {
    std::cout << "Custom deleter called." << std::endl;
    delete ptr;
}

int main() {
    // Создание shared_ptr с пользовательским делетором
    std::shared_ptr<MyResource> res_ptr(new MyResource(), custom_deleter);

    // res_ptr будет уничтожен, и будет вызван custom_deleter
    return 0;
}