将std :: make_unique与自定义删除器一起使用

时间:2014-02-14 19:36:40

标签: c++ c++11 c++14

在将std::unique_ptr与自定义删除器一起使用时,我希望使用std::make_unique而不是原始新的。我正在使用VC ++ 2013。在我看来,如果您使用自定义删除器,则无法使用std::unique_ptr。我错过了什么或者情况确实如此吗?


其他信息:

我使用std::unique_ptr<HANDLE, custom_deleter>来保存已打开的COM端口的Windows HANDLE。

我可以为此编写一个自定义RAII类,这不会非常困难,但我看到使用std::unique_ptr有多么困难/困难/不好。

3 个答案:

答案 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时,必须将删除器的类型指定为第二个模板参数,然后将适当的对象传递给构造函数。