gpt4 book ai didi

c++ - 在类中包装 Windows 句柄

转载 作者:行者123 更新时间:2023-11-28 07:41:47 25 4
gpt4 key购买 nike

我正在编写一个 C++ 框架,以便我可以重写一些软件以在多个平台上运行。我的问题与一些使用 Windows 句柄的包装器类的实现有关。考虑以下代码...

class Font
{
public:
Font(const LOGFONT& lf)
{
m_hFont = ::CreateFontIndirect(lf);
}

~Font()
{
::DeleteObject(m_hFont);
}

private:
HFONT m_hFont;
}

然后我有一个 Display 类,我可以在其中调用以下...

LOGFONT lf;
// initialise lf

Display d;
d.SetFont(Font(lf));
d.DrawText(0,0,"Some Text");

问题当然是 d.SetFont 会导致 m_hFont 被 Font 类析构函数删除。我很感激我可以在堆上创建字体并让图形类负责字体的整体“生命周期”。我想这真的是一个设计问题。是不是更好...

  1. 为包装 Windows 句柄的类实现引用计数。
  2. 在堆上创建包装类。
  3. 其他方法?

我注意到 MFC 在其包装器中有一个明确的 DeleteObject,但这当然不会导致自动资源取消分配。

感谢任何帮助/建议。

谢谢

编辑:我认为这更像是一个复制构造函数问题。 IE。我的 Font 类创建了一个 Windows FONT 句柄,但由于我按值将 Font 对象传递给显示器而被销毁。

最佳答案

您至少有三个选择:

  1. 注意“三原则”:如果一个类有一个非平凡的析构函数,那么它可能还应该实现一个复制构造函数和一个复制赋值运算符。在这种情况下,他们应该确保每个拷贝都有自己的 m_hFont 版本。

  2. 使用引用计数。

  3. 更改 Display::SetFont 以接受指向 Font 或常量引用的指针。这样,您仍然可以“在堆栈上”创建 Font,如果您只传递一个指针或对它的引用,则不会创建任何拷贝。

编辑

  1. 如果您让 Display::SetFont 直接接受 LOGFONT,您也许可以完全避免这个问题。这样,Display 类本身将管理字体(例如,删除旧的字体结构并创建新的)。如果您计划仅在上面的上下文中使用 Font 对象(使用 Display)并且字体更改很少,则此选项最有效。

    <
  2. 使 Font 类也将 LOGFONT 作为成员并仅在需要时生成 HFONT。复制时,LOGFONT 将被复制并且 HFONT 被赋予无效值。如果调用新的 Font::GetFont(比如通过 Display),那么将创建 HFONT。在字体析构函数中,如果 HFONT 不是无效值,则将其删除。如果不是所有拷贝都将用于调用 GetFont,这将避免对 CreateFontIndirect 的一些不必要的调用。

关于c++ - 在类中包装 Windows 句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15709166/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com