sergiol
sergiol

Reputation: 4335

Name of pattern / well written?

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:

  1. What is the name of the pattern?
  2. Am I doing it in the most correct way? Can I avoid to have a static variable?

Upvotes: 1

Views: 90

Answers (2)

ROX
ROX

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

knivil
knivil

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

Related Questions