所以据我所知,为了正确地实现RAII,如果我在哪里调用CreateFont,我会将它包装在一个类中,在构造函数中使用CreateFont,在析构函数中使用DeleteObject,这样当它超出作用域时,它就会清除它。
第一个问题是,我会不会有很多类这样做呢?特别是因为这个类只有一个构造函数和析构函数。
第二个问题是,如果我在WndProc中调用CreateFont类,这会经常超出范围。那么我是应该把所有的调用都调用到CreateFont,还是像WndMain中的LoadBitmap一样?我习惯于在WM_CREATE中调用这些函数,并在WM_DESTROY中清理它们。
发布于 2011-09-26 22:17:04
通过使用模板来帮助您,可以避免大量重复的工作。例如,如果使用boost::shared_ptr,则可以执行以下操作:
#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的引用计数是正确的,所以如果你想在某个地方创建它并“提升”它的寿命,你可以在它死之前把它复制到一个寿命更长的地方。
发布于 2011-09-26 22:25:46
的第一个问题是,我最终不会有很多类这样做吗?特别是因为这个类只有一个构造函数和析构函数。
是的,但有几点需要考虑:
HANDLE对象的Win32函数,它们都以相同的方式关闭(使用CloseHandle),所以你可以重用相同的类。第二个问题是,如果我在WndProc中调用CreateFont类,会经常超出作用域。
将其存储在一个不会过早超出范围的位置。:)在这里,智能指针可能再次有用。例如,只要至少有一个shared_ptr指向字体,就可以使用shared_ptr保持字体的活动状态。然后,您可以简单地将它传递到函数之外的某个常见的、寿命更长的位置。
否则,只要为RAII类实现复制构造函数和赋值运算符(在C++11中,您可能希望实现移动构造函数和移动赋值),就可以将其安全地复制(或移动)到您想要放置它的任何位置,即使它是在较小的作用域中创建的。
发布于 2011-09-26 22:19:12
的第一个问题是,我最终不会有很多类这样做吗?特别是因为该类只有一个构造函数和一个解构函数
如果您不喜欢需要为每种不同类型的对象创建的类的数量,您可以创建一个RAII类,该类在构造函数中接受HGDIOBJ参数并在析构函数中调用DeleteObject。然后,这个类可以用于所有不同的GDI对象。例如:
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中清理它们。
对于需要在内存中保留的时间超过函数作用域的项,您必须将这些项放在全局级别。
https://stackoverflow.com/questions/7556248
复制相似问题