В использовании std::unique_ptr
с пользовательским удалителем я хочу использовать std::make_unique
а не сырой новый. Я использую VC ++ 2013. Мне кажется, что нет возможности использовать std::unique_ptr
если вы используете пользовательский удалитель. Я что-то пропустил или это действительно так?
Дополнительная информация:
Я использую std::unique_ptr<HANDLE, custom_deleter>
держать Windows РУЧКУ для открытого COM-порта.
Я мог бы написать собственный класс RAII для этого, и это не было бы ужасно сложно, но я видел, как трудно / сложно / плохо это будет использовать std::unique_ptr
,
Весь смысл make_unique
это заключить в капсулу понятие «использование new
создать T
из заданных аргументов конструктора и использовать delete
уничтожить его «.
Если вы хотите пользовательское удаление, вам также нужно будет указать, как Создайте объект, и тогда больше ничего не получится от наличия функции создателя создания.
Я написал несколько примеров пользовательских функций создателя для определенных уникальных дескрипторов ресурса. в этом посте.
Вот способ обернуть управление памятью в стиле c в std::unique_ptr
использование пользовательского средства удаления, вызывающего пользовательскую бесплатную функцию. Это имеет вспомогательную функцию make, похожую на std::make_unique
ЖИТЬ:
#include <iostream>
#include <functional>
#include <memory>
// Some C style code that has some custom free function ptr...
extern "C" {
struct ABC { };
enum free_type_e {
FREE_ALL,
FREE_SOME
};
typedef void (free_f)(enum free_type_e free_type, void *ptr);
struct some_c_ops { free_f* free_op; };
void MY_free(enum free_type_e free_type, void *ptr)
{
printf("%s:%d ptr=%ld\n", __func__, __LINE__, (long)ptr);
(void)free_type;
free(ptr);
}
}; // extern "C"
template<typename T>
using c_unique_ptr = std::unique_ptr<T,std::function<void(T*)>>;
template <typename T>
c_unique_ptr<T> make_c_unique(some_c_ops* op, free_type_e free_type)
{
return c_unique_ptr<T>(static_cast<T*>(calloc(1, sizeof(T))),
std::bind(op->free_op, free_type, std::placeholders::_1));
}
void foo(c_unique_ptr<ABC> ptr)
{
std::cout << __func__ << ":" << __LINE__
<< " ptr=" << reinterpret_cast<size_t>(ptr.get()) << std::endl;
}
int main()
{
some_c_ops ops = { MY_free };
c_unique_ptr<ABC> ptr = make_c_unique<ABC>(&ops, FREE_ALL);
std::cout << __func__ << ":" << __LINE__
<< " ptr=" << reinterpret_cast<size_t>(ptr.get()) << std::endl;
foo(std::move(ptr));
std::cout << __func__ << ":" << __LINE__
<< " ptr=" << reinterpret_cast<size_t>(ptr.get()) << std::endl;
}
Возможный вывод:
main:48 ptr=50511440 foo:40 ptr=50511440 MY_free:20 ptr=50511440 main:53 ptr=0
Насколько я знаю, нет make_unique
функция в стандарте C ++ 11. Увидеть
Так что я бы предположил, что make_unique
это реализация от Microsoft, которая, по крайней мере, не включена в стандарт.
Но тем не менее вы можете использовать пользовательский удалитель с unique_ptr
, Когда используешь unique_ptr
Вы должны указать тип удалителя в качестве второго аргумента шаблона, а затем передать соответствующий объект конструктору.