c++ - 我应该如何将 getDC 用作具有自动清理功能的本地对象? C++

标签 c++ gdi

我是 C++ 的新手,正在学习如何做的最佳方法。 我看到了很多关于绘画的有用示例,但是我没有看到任何带有智能类的简单 pimple getdc。

所以我自己写了一个:

class DCObject 
{
public:
    DCObject(HWND handle)
    {
        my_handle = handle;
        my_hdc = GetDC(my_handle);
    }

    HDC GetHDC() {
        return my_hdc;
    }

    ~DCObject()
    {
        ReleaseDC(my_handle, my_hdc);
    }
private:
    HWND my_handle;
    HDC my_hdc;
};

我试着像这样获得 hdc:

HDC mydc = DCObject(dialog_item_handle).GetHDC();

这是正确的吗?要询问类方法,首先不创建类对象?在这种情况下,类会发生什么?也许我确实得到了 hdc 并且它立即被释放了?(它有效但它可能会产生 hdc 的未定义行为?)

也许我应该这样做:

DCObject myhdcobj(dialog_item_handle);
 HDC mydc = myhdcobj.GetHDC();

最佳答案

声明

HDC mydc = DCObject(dialog_item_handle).GetHDC();

调用 DCObject 构造函数,创建一个临时对象。一个临时对象在完整表达式的末尾被(保证)销毁。所以在这条语句之后临时对象被销毁了,它的析构函数调用了ReleaseDC

解决方案:存储对象而不是句柄,

const DCObject mydc( dialog_item_handle );

我更愿意这样写

auto const mydc = DCObject( dialog_item_handle );

… 但是对于问题中出现的 DCObject 类,这是不安全,因为没有复制/移动处理,所以临时对象的析构函数对了,会调用ReleaseDC...


要为常量声明启用更自然的 auto 表示法,并且通常要启用移动和禁用复制,请执行以下操作:

class DCObject 
{
private:
    HWND my_handle;
    HDC my_hdc;

    DCObject( DCObject const& ) = delete;
    DCObject& operator=( DCObject const& ) = delete;

public:
    auto handle() const -> HDC { return my_hdc; }

    ~DCObject()
    { ReleaseDC( my_handle, my_hdc ); }

    DCObject( const HWND handle )
        : my_handle( handle )
        , my_hdc( GetDC( handle ) )
    {}

    DCObject( DCObject&& other )
        : my_handle( other.my_handle )
        , my_hdc( other.my_hdc )
    { other.my_hdc = 0; }
};

其他类型句柄的代码——甚至是设备上下文句柄的其他用途——将非常相似。

将其表达为通用类模板所需的一个主要见解是清理所需的附加状态,例如这里的窗口句柄可以是指定清理函数或类函数对象的一部分,特别是作为 lambda 中的捕获。

如果您还没有使用 lambda,请记住这一点。

您也可以在不使用 lambda 的情况下使用有状态删除器的原理。

关于c++ - 我应该如何将 getDC 用作具有自动清理功能的本地对象? C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27610994/

相关文章:

c++ - 用一行代码替换字符串中所有句点的 C++ 方法?

c++ - 如何使用C++将MP3转换为PCM?

无法使用 EnumDisplaySettings 获取所有设备的显示分辨率

c++ - 我应该使用 Direct3D 还是仅使用 Windows GDI 来获得精美/高性能的 Win32 应用程序 UI?

C++ STL 比较映射找不到(运算符==)

c++ - OpenBLAS 仅为一个例程设置线程数

c++ - 关于 unsigned int 的建议(江南 Style 版)

c++ - 使用 C++ 和 GDI 分析屏幕截图以获得屏幕的平均颜色

c++ - 如何从 HMENU 获取菜单 ID?

c++ - 绘制和创建内存缓冲区 (Windows GDI)