Назад к вопросам
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;
}