Reputation: 4335
I have the following code:
Doc header file
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;
}
};
}
Doc source file
Static variable initialization:
bool CMyDoc::Suspender::m_suspending = false;
Check if it is on the "not allowed" to do things state, and if so, don't do them:
void CMyDoc::SomeMethod()
{
if (!Suspender::IsSuspending())
DoThings();
}
Somewhere where I want to run some code on the "not allowed" state
Declare a variable of the Suspender
type. Automatically will put on the "not allowed state" on the declaration. But the greatest benefit is it will return itself back to the "allowed" state when the stack frame ends, as it passes on the s
variable's destructor.
void CMyView::DoSomething()
{
CMyDoc::Suspender s;
((CMyDoc*) GetDocument())->SomeMethod();
}
QUESTIONS:
Upvotes: 1
Views: 90
Reputation: 1266
No, I don't think you are doing it in the most correct way, and because of the flaw in it I don't think its really RAII either.
The flaw I believe is there can be demonstrated without threads.
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();
}
This particular issue could be addressed by replacing the bool with an int to allow nested suspension. The int would be incremented by each suspender and suspension would be off if the value = 0.
(In the past I have successfully used such a pattern to control repetitive redraws)
Upvotes: 1
Reputation: 807
1.) m_suspending
is a property of CMyDoc
because its behavior depends on it. Therefore it should be a member variable of CMyDoc
.
2.) If Suspender
can be created within multiple threads then m_suspending
should be synchronized. And global variables are bad anyway.
3.) RAII is the keyword and your example looks similar to the way how mutex
and lock_guard
interact.
4.) You do not need a name for every trivial "pattern". RAII is fundamental in C++.
Upvotes: 0