std::make_unique 对于 GDI+ 对象

std::make_unique for GDI+ objects

由于自动内存管理的好处,我正在尝试将 std::unique_ptr 用于我的 gdi+ 对象。

看看这个标准的 gdi+ C 风格代码:

Gdiplus::Graphics* graphics = Gdiplus::Graphics::FromImage(image);
graphics->DrawRectangle(/* parameters */); // Working

我知道我可以使用 std::unique_ptr 如下:

std::unique_ptr<Gdiplus::Graphics> graphics(Gdiplus::Graphics::FromImage(image));
graphics->DrawRectangle(/* parameters */); // Working

现在我想用 std::make_unique 构造 std::unique_ptr 但我无法编译它。

我试过以下方法:

std::unique_ptr<Gdiplus::Graphics> graphics = std::make_unique<Gdiplus::Graphics>(Gdiplus::Graphics::FromImage(image));
graphics->DrawRectangle(/* parameters */); // Not working

但是我得到以下转换错误: C2664 从 "Gdiplus::Graphics" 到 "HDC" 的 1 个参数的转换是不可能的。

我使用的是最新版本的VS2015

我认为std::make_unique应该这样使用:

std::unique_ptr<T> varName = std::make_unique<T>(argument with which an instance of T will be constructed);

我做错了什么?

I thought std::make_unique it should be used like this:

std::unique_ptr<T> varName = std::make_unique<T>(argument with which an instance of T will be constructed);

What am I doing wrong?

您没有构建实例。您正在调用一个为您构造实例的函数,因此无法在此处使用 std::make_unique

实际上,std::make_unique<T>(args...) 调用了 T::T(args...)(通过适当的转发)。因此,在您的情况下,您正在调用类型为 Gdiplus::Graphics*Gdiplus::Graphics 构造函数,这不是您想要的。你不希望 make unique 在这里。但是您可以创建自己的函数,这会稍微缩短语法。

std::unique_ptr<Gdiplus::Graphics> make_graphics(/*whatever image is*/ image)
{
    return std::unique_ptr<Gdiplus::Graphics>(Gdiplus::Graphics::FromImage(image));
}

此外,正如评论中提到的 gurka,一旦 std::unique_ptr 超出范围,它的内容将使用 delete 运算符销毁。如果必须使用自定义释放方​​法销毁 Gdiplus::Graphics*,则必须将其提供给 std::unique_ptr 构造函数(如 std::unique_ptr<T, decltype(destroy_T)>(arg, destroy_T)