我有以下代码:
文档标题文件
class CMyDoc
{
public:
class Suspender
{
friend class CMyDoc;
static bool m_suspending;
inline static const bool IsSuspending() { return m_suspending; }
public:
Suspender()
{
m_suspending = true;
}
~Suspender()
{
m_suspending = false;
}
};
}
文档源文件
静态变量初始化:
bool CMyDoc::Suspender::m_suspending = false;
检查它是否处于“不允许”状态,如果是,请不要这样做:
void CMyDoc::SomeMethod()
{
if (!Suspender::IsSuspending())
DoThings();
}
我希望在“不允许”状态下运行某些代码的地方
声明Suspender
类型的变量。自动将声明上的“不允许状态”。但最大的好处是它会在堆栈帧结束时返回到“允许”状态,因为它传递给s
变量的析构函数。
void CMyView::DoSomething()
{
CMyDoc::Suspender s;
((CMyDoc*) GetDocument())->SomeMethod();
}
问题:
答案 0 :(得分:1)
不,我不认为你是以最正确的方式做到这一点,而且由于其中的缺陷我也不认为它真的是RAII。
我相信这个缺陷可以在没有线程的情况下得到证明。
void SomeViewMethod()
{
Suspender s1;
((CMyDoc*) GetDocument())->SomeMethod();
}
SomeOtherViewMethod()
{
Suspender s2;
((CMyDoc*) GetDocument())->SomeMethod();
SomeViewMethod();
// this looks like suspender s2 should be suspending the next call...
// but when the s1 inside SomeViewMethod went out of scope it turned off suspending
((CMyDoc*) GetDocument())->SomeMethod();
}
可以通过用int替换bool来解决此特定问题,以允许嵌套暂停。每个吊杆都会增加int,如果值= 0,则暂停将关闭。
(过去我已成功使用这种模式来控制重复重绘)
答案 1 :(得分:0)
1。)m_suspending
是CMyDoc
的属性,因为它的行为取决于它。因此它应该是CMyDoc
的成员变量。
2.。)如果可以在多个线程中创建Suspender
,则应同步m_suspending
。无论如何,全局变量都很糟糕。
3.。)RAII是关键字,您的示例与mutex
和lock_guard
的互动方式类似。
4。)你不需要每个琐碎的模式的名称"。 RAII是C ++的基础。