2017-02-27 2 views
1

私は次のコードを持っている:それは上にある場合パターンの名前/よく書かれていますか?

bool CMyDoc::Suspender::m_suspending = false; 

チェック:

ドクヘッダファイル

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; 
     } 
    }; 
} 

ドク・ソース・ファイル

static変数の初期化を"許可され​​ていない"状態を行うことができます。もしそうなら、それをしない:私は「許されない」状態

Suspender型の変数を宣言上のいくつかのコードを実行したい

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

どこか自動的に宣言に「許可されていない状態」が設定されます。しかし、最大のメリットは、変数がデストラクタsを通過するときにスタックフレームが終了したときに "許可"状態に戻ることです。

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

質問

  1. パターンの名前は何ですか?
  2. 私は最も正しい方法でそれをやっていますか?静的変数を持つことを避けることはできますか?
+2

これは[コードに適しであろうレビュー](http://codereview.stackexchange.com/)。 – Quentin

+1

RAIIの使用です。 – Jarod42

答えて

0

1)m_suspendingは、その動作がそれに依存するため、CMyDocのプロパティです。したがって、メンバー変数はCMyDocである必要があります。

2.)Suspenderを複数のスレッドで作成できる場合は、m_suspendingを同期させる必要があります。とにかくグローバル変数は悪いです。

3.)RAIIがキーワードであり、あなたの例は、mutexlock_guardがどのようにやり取りするかと似ています。

4.)すべての簡単な「パターン」の名前は必要ありません。 RAIIはC++の基本です。

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(); 
} 

この特定の問題は、ネストされた中断を許可するためにboolをintに置き換えることで対処できます。 INTは各サスペンダーだけインクリメントされると場合、値は= 0

懸濁液がオフになり(以前はIが正常繰り返し再描画を制御するようなパターンを使用している)

+0

あなたがしたことの名前は**参照カウントです** – sergiol

関連する問題