Делиторы – это специальные функции, которые определяют, как должен уничтожаться объект при освобождении памяти умным указателем.
Обычно
std::unique_ptr и std::shared_ptr по умолчанию вызывают delete, но иногда это поведение нужно изменить. 🚩Когда нужны делиторы?
🟠Для работы с нестандартными ресурсами (не `new`)
Например, если объект создан через
malloc(), fopen(), CreateFile(), то delete не подходит! 🟠Если нужно логировать или выполнять доп. действия при удалении
Можно добавить
std::cout, логику очистки, сброс ресурсов. 🟠Если объект хранится в массиве (`new[]`)
delete не удалит массив корректно, нужно delete[]. 🟠Если ресурс должен освобождаться особым способом
Например, в
std::shared_ptr можно передать free(), fclose() или CloseHandle(). 🚩Как передавать делитор в `std::unique_ptr`?
Пример: освобождение памяти от
malloc() через std::free()#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int, void(*)(void*)> ptr(malloc(sizeof(int)), free);
*reinterpret_cast<int*>(ptr.get()) = 42;
std::cout << "Значение: " << *reinterpret_cast<int*>(ptr.get()) << "\n";
}
Здесь
free используется вместо delete, потому что память выделена malloc(). Пример: закрытие файла через
std::fclose()#include <iostream>
#include <memory>
#include <cstdio>
int main() {
std::unique_ptr<FILE, decltype(&std::fclose)> file(fopen("test.txt", "w"), &std::fclose);
if (file) {
std::fprintf(file.get(), "Hello, world!\n");
}
} // `fclose(file)` вызовется автоматически!
🚩Как передавать делитор в `std::shared_ptr`?
В
std::shared_ptr можно передавать делитор прямо в конструкторе#include <iostream>
#include <memory>
void customDeleter(int* ptr) {
std::cout << "Удаляю объект: " << *ptr << "\n";
delete ptr;
}
int main() {
std::shared_ptr<int> ptr(new int(100), customDeleter);
} // В конце `customDeleter(ptr)` вызовется автоматически!
🚩Делитор для массивов (`delete[]`)
По умолчанию
std::unique_ptr<int[]> сам вызывает delete[], но если std::unique_ptr<int> используется неправильно, то delete удалит только первый элемент массива! Ошибка:
delete вместо delete[]std::unique_ptr<int> arr(new int[10]); // ОШИБКА! `delete` вызовет утечку памяти!
Правильный вариант
std::unique_ptr<int[], std::default_delete<int[]>> arr(new int[10]);
Ставь 👍 и забирай 📚 Базу знаний