【问题标题】:How to use a custom deleter using WinAPI with std::make_unique?如何使用带有 std::make_unique 的 WinAPI 使用自定义删除器?
【发布时间】:2021-02-23 05:58:46
【问题描述】:

所以我只是在试验智能指针以及如何使用它们管理 Win32 HANDLE 对象,所以我想测试我编写的这个简单代码。

它应该为std::unique_ptr 提供一个自定义删除器,以便在智能指针超出范围时使用。

template <typename Function>
class PtrDeleter
{
    Function _Closer;
public:
    void operator()(void* memBlock) const
    {
        _Closer(memBlock);
    }
};

//The std::make_unique is the one causing the problem...
std::unique_ptr<void*, PtrDeleter<decltype(CloseHandle)>> ptr = std::make_unique<void*>(OpenThread(...));

我为Function 参数使用模板的原因是因为我将在CloseHandle 中使用其他函数,例如CoTaskMemFree

无法从 std::unique_ptr>' 转换为 'std::unique_ptr>

这是编译器输出的。为什么它还在尝试将std::default_deletestd::make_unique 一起使用?

【问题讨论】:

标签: c++ winapi stl smart-pointers


【解决方案1】:

make_unique 返回带有默认删除器的unique_ptr

要提供您的自定义版本,您必须调用unique_ptr(Pointer,Deleter) 版本的unique_ptr ctor:

template <typename Function>
class PtrDeleter {
    Function _Closer;
public:
    void operator()(void* memBlock) const {
        _Closer(memBlock);
    }
};

int main() {
    PtrDeleter<decltype(&CloseHandle)> deleter;
    void* openThread = OpenThread(0,false,0);
    std::unique_ptr<void, decltype(deleter)> ptr(openThread,deleter);
}

Demo

【讨论】:

  • make_unique 也是在堆上分配对象,这不是我们这里想要的。该功能根本不适合这里。与 new 相比,它也没有像 make_shared 这样的性能优势。
【解决方案2】:

std::make_unique 无法使用自定义删除器生成 std::unique_ptr。 你必须手动调用它的构造函数。

std::unique_ptr<void*, PtrDeleter<decltype(&CloseHandle)>> ptr{nullptr, CloseHandle}

在你的情况下,它可以简化为

std::unique_ptr<void*,decltype(&CloseHandle)> ptr{nullptr, CloseHandle}

无需制作仿函数。

【讨论】:

    猜你喜欢
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 2022-06-23
    相关资源
    最近更新 更多