0Pricing
C++ Academy · Урок

Пользовательские удалители и функции make

Используйте std::make_unique, std::make_shared и пользовательские удалители для ресурсов, отличных от памяти.

«Пользовательские удалители и функции make» — бесплатный урок C++ Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Зачем нужны пользовательские удалители

Не каждый ресурс освобождается с помощью delete. Для дескрипторов файлов, сокетов, ресурсов, специфичных для OS, и массивов нужны разные функции очистки.

Удалитель по умолчанию для unique_ptr

По умолчанию unique_ptr<T> использует delete. Для массивов используйте unique_ptr<T[]>, который вызывает delete[].

Задание пользовательского удалителя

Передайте вызываемый объект как второй аргумент шаблона. Удалитель получает необработанный указатель и освобождает его подходящим способом.

auto closer = [](FILE* f) { if (f) std::fclose(f); };
std::unique_ptr<FILE, decltype(closer)> file(
    std::fopen("data.txt", "r"), closer);

Удалитель для shared_ptr

shared_ptr хранит свой удалитель в управляющем блоке — его тип стирается, поэтому сам тип shared_ptr не изменяется.

std::shared_ptr<FILE> file(
    std::fopen("data.txt", "r"),
    [](FILE* f) { if (f) std::fclose(f); }
);

Распространённые случаи использования пользовательских удалителей

Примеры из практики:

  • Дескрипторы библиотек C (FILE*, sqlite3*, дескрипторы curl)
  • Ресурсы OS (HANDLE в Windows, fd в Unix)
  • Пользовательские пулы памяти
  • Внешние объекты со счётчиком ссылок

std::make_unique (C++14)

Рекомендуемый способ создания unique_ptr. Передаёт аргументы конструктору и позволяет не использовать необработанный new.

auto p = std::make_unique<Widget>(arg1, arg2);

Зачем нужен make_unique

Три преимущества:

  • Безопасность при исключениях — в коде пользователя нет необработанного new
  • Не нужно дважды указывать тип
  • Нельзя случайно передать необработанный указатель двум unique_ptr

std::make_shared

Для shared_ptr функция make_shared выделяет управляющий блок и объект одной операцией в куче — это быстрее, чем раздельное выделение памяти.

auto p = std::make_shared<Widget>(arg1, arg2);

Когда у make_shared есть недостатки

Из-за единого выделения память объекта освобождается только после того, как исчезнут все weak_ptr. Если weak_ptr живут дольше shared_ptr, предпочитайте создание в два шага.

Сочетание пользовательских удалителей с функциями make

make_unique и make_shared напрямую не принимают пользовательский удалитель. В таком случае создайте интеллектуальный указатель вручную.

// make_shared cannot take a deleter
std::shared_ptr<FILE> file(
    std::fopen("data.txt", "r"),
    [](FILE* f) { if (f) std::fclose(f); }
);

Подводный камень: тип лямбды как параметр шаблона

Каждая лямбда имеет уникальный тип. Для unique_ptr при объявлении используйте decltype(my_deleter); либо используйте именованную функцию или указатель на функцию, чтобы упростить типы.

Быстрая проверка

Какая фабричная функция позволяет выделить std::shared_ptr и его управляющий блок одной операцией в куче?

Итоги

В обычных случаях используйте make_unique и make_shared. Предоставляйте пользовательский удалитель (лямбду или функцию), когда для ресурса требуется нечто большее, чем delete, — например, для дескрипторов файлов, объектов OS или очистки ресурсов библиотеки C.

Часто задаваемые вопросы

Урок «Пользовательские удалители и функции make» бесплатный?

Да — полный текст урока «Пользовательские удалители и функции make» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Пользовательские удалители и функции make»?

Используйте std::make_unique, std::make_shared и пользовательские удалители для ресурсов, отличных от памяти. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Пользовательские удалители и функции make»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Почему умные указатели заменяют обычные new и delete
  2. unique_ptr: исключительное владение
  3. shared_ptr и weak_ptr: совместное владение
  4. Пользовательские удалители и функции make
← Назад к C++ Academy