图案的名称 /写得很好

Name of pattern / well written?

本文关键字:很好      更新时间:2023-10-16

我有以下代码:

DOC标头文件

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源文件

静态变量初始化:

bool CMyDoc::Suspender::m_suspending = false;

检查它是否在"不允许"执行状态上,如果是,请不要这样做:

void CMyDoc::SomeMethod()
{
    if (!Suspender::IsSuspending())
        DoThings();
}

我想在"不允许"状态

上运行一些代码

声明Suspender类型的变量。自动将在声明上放置"不允许的状态"。但是最大的好处是,当堆栈框架结束时,它将返回"允许"状态,因为它通过s变量的破坏者。

void CMyView::DoSomething()
{
    CMyDoc::Suspender s;
    ((CMyDoc*) GetDocument())->SomeMethod();
}

问题

  1. 该模式的名称是什么?
  2. 我是以最正确的方式做的吗?我可以避免有一个静态变量吗?

不,我不认为您以最正确的方式进行操作,并且由于其中存在缺陷,我也不认为它确实是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允许嵌套悬架代替布尔来解决这个特定问题。如果值= 0。

(过去,我成功地使用了这样的模式来控制重复的redraws)

1。) m_suspendingCMyDoc的属性,因为其行为取决于它。因此,它应该是CMyDoc的成员变量。

2。)如果可以在多个线程中创建Suspender,则应同步m_suspending。无论如何,全局变量都很糟糕。

3。)raii是关键字,您的示例看起来与mutexlock_guard交互的方式相似。

4。)您不需要每个微不足道的"模式"名称。RAII在C 中是基本的。