C++ C++;拉伊问题
因此,据我所知,要正确实现RAII,如果我在何处调用C++ C++;拉伊问题,c++,windows,raii,C++,Windows,Raii,因此,据我所知,要正确实现RAII,如果我在何处调用CreateFont,我会将其包装在一个类中,在构造函数中使用CreateFont,在析构函数中使用DeleteObject,这样当它超出范围时,它会将其清除 第一个问题是,我会不会有很多班级都这样做?特别是因为类只有构造函数和析构函数 第二个问题是,如果我在WndProc中调用CreateFont类,它会不断超出范围。那么我应该在WndMain中调用CreateFont或类似的LoadBitmap? 我习惯于在WM\u CREATE中调用这些
CreateFont
,我会将其包装在一个类中,在构造函数中使用CreateFont
,在析构函数中使用DeleteObject
,这样当它超出范围时,它会将其清除
第一个问题是,我会不会有很多班级都这样做?特别是因为类只有构造函数和析构函数
第二个问题是,如果我在WndProc中调用CreateFont类,它会不断超出范围。那么我应该在WndMain中调用CreateFont
或类似的LoadBitmap
?
我习惯于在
WM\u CREATE
中调用这些函数,并在WM\u DESTROY
中清理它们,通过使用模板帮助您可以避免大量重复工作。例如,如果使用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));
}
#包括
#包括
结构字体;
Font*createFont();
作废删除字体(字体*);
int main(){
boost::shared_ptr font(createFont(),std::ptr_fun(deleteFont));
}
这样可以节省编写自定义类来管理资源的时间。如果您无法使用boost和TR1或更新版本,您仍然可以自己实现类似的通用工具来提供帮助
boost::shared_ptr
的引用计数正确,因此,如果您想在某个地方创建它并“提升”它以使它更长寿,您可以通过在它死之前将它复制到长寿的地方来实现
第一个问题是,我会不会有很多班级都这样做?特别是因为类只有构造函数和解构器
如果您不喜欢为每种不同类型的对象创建的类的数量,可以创建一个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类,它会不断超出范围。那么我应该在WndMain中调用CreateFont或类似LoadBitmap吗?我习惯于在WM_CREATE中调用这些函数,并在WM_DESTROY中清理它们
对于需要在内存中保留超过函数作用域时间的项,您必须将它们放在全局级别。如果您要使用solid RAII,有一些选项可以减少您需要的类的数量-例如,一些boost智能指针(特别是共享的ptr)允许您提供自己的函数,以便在指针超出范围时调用 否则,是的-您将拥有一个用于任何需要显式释放的资源的类-尽管这在代码方面是一个难题,但从长远来看,它将为您节省大量调试时间(尤其是在组项目中)。不过,我还是想说,根据您自己对情况的感受使用RAII——在任何地方使用它都是一个好主意,但有时在转换旧代码时,修复所有调用链以使用它可能需要大量的工作 还有一件事——我对您使用的GUI逻辑不太熟悉,所以我不会专门去那里。。。但是,您必须研究如何复制资源,以及应将其保留多长时间。您的RAII容器是引用计数还是具有值(复制)语义?引用计数智能指针(如shared_ptr)可以解决您经常重新创建资源的问题,只要您可以在代码周围传递对原始资源的引用 第一个问题是,我会不会有很多班级都这样做?特别是因为类只有构造函数和析构函数 是的,但有几点需要考虑:
- 这是个问题吗?课程规模小,易于阅读和理解
- 您可能能够重用其中的许多对象(例如,有许多Win32函数创建
对象,并且它们都以相同的方式关闭(使用HANDLE
),因此您可以为这些对象重用同一类CloseHandle
- 您可以使用智能指针或其他一些通用包装器来填充大多数样板代码。最流行的智能指针类允许您指定自定义删除器函数
shared_ptr
可以用来保持字体的活动状态,只要至少有一个shared_ptr
指向它。然后,您可以简单地将其从函数传递到一些常见的长寿命位置
否则,只要您为RAII类实现复制构造函数和赋值运算符(在C++11中,您可能希望实现移动构造函数和移动赋值),它就可以安全地复制(或移动)到您想要放置它的任何位置,即使它是在较小的范围内创建的。还有比将RAII对象置于全局级别更好的选项。我想到的一点是:不要将RAII用于范围结束时不会发布的资源。使用RAII的全部目的是为了自动处理资源。如果全局项未使用RAII处理,则应用程序必须手动释放这些项。但是管理资源的全局对象很简单。无论如何,清理这些全局对象需要一些手工工作。是的,最终会有很多类。这就是所有Win32 API包装库最终拥有的功能。也有一个很好的理由,这与RAII无关。Win32 API,特别是GDI部分,有很多概念需要包装!不管你是否使用RAII,你都会得到
窗口
,设备
,画师
,字体
,位图
。。。上课。