首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++ RAII问题

C++ RAII问题
EN

Stack Overflow用户
提问于 2011-09-26 22:00:37
回答 4查看 917关注 0票数 10

所以据我所知,为了正确地实现RAII,如果我在哪里调用CreateFont,我会将它包装在一个类中,在构造函数中使用CreateFont,在析构函数中使用DeleteObject,这样当它超出作用域时,它就会清除它。

第一个问题是,我会不会有很多类这样做呢?特别是因为这个类只有一个构造函数和析构函数。

第二个问题是,如果我在WndProc中调用CreateFont类,这会经常超出范围。那么我是应该把所有的调用都调用到CreateFont,还是像WndMain中的LoadBitmap一样?我习惯于在WM_CREATE中调用这些函数,并在WM_DESTROY中清理它们。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-09-26 22:17:04

通过使用模板来帮助您,可以避免大量重复的工作。例如,如果使用boost::shared_ptr,则可以执行以下操作:

代码语言:javascript
复制
#include <boost/shared_ptr.hpp>
#include <functional>

struct Font;

Font *createFont();
void deleteFont(Font*);

int main() {    
  boost::shared_ptr<Font> font(createFont(), std::ptr_fun(deleteFont));
}

这样就省去了编写自定义类来管理资源的麻烦。如果boost和TR1或更新版本对您不可用,您仍然可以自己实现一些类似和通用的工具来提供帮助。

boost::shared_ptr的引用计数是正确的,所以如果你想在某个地方创建它并“提升”它的寿命,你可以在它死之前把它复制到一个寿命更长的地方。

票数 10
EN

Stack Overflow用户

发布于 2011-09-26 22:25:46

的第一个问题是,我最终不会有很多类这样做吗?特别是因为这个类只有一个构造函数和析构函数。

是的,但有几点需要考虑:

  • 这是个问题吗?这些类很小,易于阅读和理解,你可以重用它们中的许多(例如,有很多创建HANDLE对象的Win32函数,它们都以相同的方式关闭(使用CloseHandle),所以你可以重用相同的类。
  • 你可以使用智能指针或其他一些通用的包装器来填充大多数样板代码。最流行的智能指针类允许您指定自定义删除函数。

第二个问题是,如果我在WndProc中调用CreateFont类,会经常超出作用域。

将其存储在一个不会过早超出范围的位置。:)在这里,智能指针可能再次有用。例如,只要至少有一个shared_ptr指向字体,就可以使用shared_ptr保持字体的活动状态。然后,您可以简单地将它传递到函数之外的某个常见的、寿命更长的位置。

否则,只要为RAII类实现复制构造函数和赋值运算符(在C++11中,您可能希望实现移动构造函数和移动赋值),就可以将其安全地复制(或移动)到您想要放置它的任何位置,即使它是在较小的作用域中创建的。

票数 4
EN

Stack Overflow用户

发布于 2011-09-26 22:19:12

的第一个问题是,我最终不会有很多类这样做吗?特别是因为该类只有一个构造函数和一个解构函数

如果您不喜欢需要为每种不同类型的对象创建的类的数量,您可以创建一个RAII类,该类在构造函数中接受HGDIOBJ参数并在析构函数中调用DeleteObject。然后,这个类可以用于所有不同的GDI对象。例如:

代码语言:javascript
复制
class GDIObject
{
public:
    HGDIOBJ GdiObject;

    GDIObject( HGDIOBJ object )
        : GdiObject( object )
    {
    }

    ~GDIObject()
    {
        DeleteObject( GdiObject );
    }
}

...

GDIObject font( CreateFont( 48, 0, 0, 0, FW_DONTCARE, false, true, false, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Impact") ) );

第二个问题是,如果我在WndProc中调用CreateFont类,会经常超出作用域。那么我是应该把所有的调用都调用到CreateFont,还是像WndMain中的LoadBitmap一样?我习惯于在WM_CREATE中调用这些函数,并在WM_DESTROY中清理它们。

对于需要在内存中保留的时间超过函数作用域的项,您必须将这些项放在全局级别。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7556248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档