在将std::unique_ptr
与自定义删除器一起使用时,我希望使用std::make_unique
而不是原始新的。我正在使用VC ++ 2013。在我看来,如果您使用自定义删除器,则无法使用std::unique_ptr
。我错过了什么或者情况确实如此吗?
其他信息:
我使用std::unique_ptr<HANDLE, custom_deleter>
来保存已打开的COM端口的Windows HANDLE。
我可以为此编写一个自定义RAII类,这不会非常困难,但我看到使用std::unique_ptr
有多么困难/困难/不好。
答案 0 :(得分:24)
make_unique
的重点是封装“使用new
从给定构造函数参数创建T
并使用delete
的概念摧毁它“。
如果你想要一个自定义删除器,你还必须指定如何创建该对象,然后再没有从拥有制作器功能中获得更多。
我为某些独特的资源句柄in this post编写了一些自定义制作者函数的示例。
答案 1 :(得分:0)
这是一种使用调用自定义自由函数的自定义删除器将c样式内存管理包装到std::unique_ptr
的方法。这有一个类似于std::make_unique
LIVE的make函数助手:
#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
答案 2 :(得分:-2)
据我所知,C ++ 11标准中没有make_unique
函数。参见
所以我假设make_unique
是Microsoft的一个实现,至少不包含在标准中。
但是,您可以使用unique_ptr
的自定义删除工具。使用unique_ptr
时,必须将删除器的类型指定为第二个模板参数,然后将适当的对象传递给构造函数。