2012-03-31 7 views
1

"safe flag"パターンを実装するクラスの小さなセットを作成しようとしています。安全なORrableフラグを表すクラスを作成する際に問題が発生しました

class MyClass; 

class CreateFlag 
{ 
friend class MyClass; 

private: 
    int value; 

    CreateFlag(int newValue) 
    { 
     value = newValue; 
    } 

public: 
    CreateFlag operator | (const CreateFlag & right) const 
    { 
     int newValue = value | right.value; 
     return CreateFlag(newValue); 
    } 

    CreateFlag(const CreateFlag && flag) 
    { 
      value = flag.value; 
    } 

    CreateFlag(const CreateFlag & flag) 
    { 
     value = flag.value; 
    } 

    static const CreateFlag Flag1; 
    static const CreateFlag Flag2; 
    static const CreateFlag Flag4; 
}; 

const CreateFlag CreateFlag::Flag1 = CreateFlag(1); 
const CreateFlag CreateFlag::Flag2 = CreateFlag(2); 
const CreateFlag CreateFlag::Flag4 = CreateFlag(4); 

class MyClass 
{ 
public: 
    static void DisplayFlag(CreateFlag flag) 
    { 
     printf("Flag value: %d\n", flag.value); 
    } 
}; 

int main(int argc, char * argv) 
{ 
    MyClass::DisplayFlag(CreateFlag::Flag1 | CreateFlag::Flag2); 

    getchar(); 
} 

問題はCreateFlagがプライベートctorのを(意図的であるものを)持っていること、であるので、CreateFlagの静的フィールドの値と、上記のコードを指定する方法はありません。私はそのような何かを思い付いてきましたコンパイルされません。あり

MyClass::DisplayFlag(CreateFlag::Flag1() | CreateFlag::Flag2()); 

この制限を回避する方法はCreateFlagのインスタンスを返す静的メソッドにstaticフィールドを変更することですが、あなたのようなmetodを呼び出す必要がありますように、そのは、汚いソリューションです直接ソリューションですか?何かが変更された場合、フラグ定義はMyClassクラスにも移動できます。

私も知っている

、静的フィールドのC++ 11のサポートインプレース初期化が、生憎VC++ 10は、まだこの構文をサポートしていません...

編集私が変更されました誰もがそれをコピーして使用できるように、現在コンパイルして意図したとおりに動作します。

答えて

2

上記のコードはコンパイルされませんが、期待していた以上の理由でコンパイルされていないと思います。具体的には、コンパイルエラーがこの行にあります。

MyClass::DisplayFlag(CreateFlag::Flag1 | CreateFlag::Flag2); 

理由はDisplayFlagが値によってそのCreateFlag引数を取り、そしてあなたはコピーコンストラクタのプライベートをマークしたということです。

人々が無効な値を一緒にORできないようにするには、コピーコンストラクタをプライベートにする必要はないと思います。あなたが知っていることを知っているCreateFlagのコピーを作成しても、クライアントはこれまでできなかったことを何もすることができません。コピーコンストラクタの定義を省略し、C++のデフォルトのコピーサポートがうまくいくようにしたら、ちょうど良いはずです。

エラーが発生したと思われる行は、問題が発生していないようです。 It compiles just fineコピーコンストラクタを削除すると、

希望すると便利です。

+0

Oh poor me。私は間違いを訂正しましたが、PoC全体を変更した直後に気づいていないので、実際には機能します。それは、静的フィールド初期化子がクラスと同じスコープアクセスを持ち、どのフィールドが初期化されているのかを意味しますか? – Spook

+0

@ Spook-私はそう信じています、それは論理的にクラスの一部です。 – templatetypedef

+0

今はすべてがクリアです。手伝ってくれてありがとう! – Spook

関連する問題