状態、オプションなどを表すためにバイナリフラグを使用する

StackOverflow https://stackoverflow.com/questions/1407197

  •  05-07-2019
  •  | 
  •  

質問

状態やオプション、またはバイナリの「フラグ」を使用して同様のものを表現したい場合それらを渡して OPTION1 |のようなオブジェクトに保存できるようにOPTION2 OPTION1 は0001、 OPTION2 は0010であるため、渡されるものは0011であり、オプションの組み合わせを表します。

C ++でこれを行うにはどうすればよいですか?私は次のようなものを考えていました

enum Option {
    Option_1 = 0x01,
    Option_2 = 0x02,
    Option_3 = 0x04,
    //...
}

void doSomething(Option options) {
    //...
}

int main() {
    doSomething(Option_1|Option_2);
}

しかし、理想的には、 doSomething は指定されたOptionの解釈方法を知っています。

私は正しい軌道に乗っていますか?もっと良い方法はありますか?

更新

また、考えられるすべての組み合わせに対して Option を定義する必要はありませんか?

役に立ちましたか?

解決

これは、これらのことを行う一般的な方法です。 doSomething は、ビット単位の and 演算子を使用して、オプションが選択されているかどうかを確認できます。

if (options & Option_1){ 
  // option 1 is selected
}

または、ビットフィールド

struct Options {
    unsigned char Option_1 : 1;
    unsigned char Option_2 : 1;
};

Options o;
o.Option_1 = 1;
o.Option_2 = 0;

他のヒント

それが私がやる方法だろう。ただし、列挙をもう少し読みやすくするために使用できる多くのトリックがあります。

enum Option {
    Option1 = 1 /*<< 0*/,
    Option2 = 1 << 1,
    Option3 = 1 << 2,
    // etc.
};

さらに、列挙にはビット演算子を指定する必要があります。これを支援する ASLの enum_ops ユーティリティのようなものを検討してください。

人々が通常そのようなフラグを使用する方法は、次のように関数を定義することであることに注意してください:

void doSomething( unsigned int options ) 
{
    //...
}

他のすべてはあなたが望むように正確に動作します:)

もう1つの方法は、独自の「フラグ」を作成することです。クラス。クラスには次のような関数がいくつかあります:

bool GetOption( Option option )
{
    return (m_Option & option) > 0;
}

void SetOption( Option option )
{
    m_Option |= option;
}

void ClearOption( Option option )
{
    m_Option &= ~option;
}

または演算子をオーバーロードして、希望どおりに実行します:

Flags( unsigned int options ) :
   m_Option( options )
{
}

Flags operator|( const Flags& flags )
{
    return Flags( m_Option | flags.m_Option );
}

など。

stlビットセットを確認してください。一部の人々は、Cスタイルのビットフラグの代わりにそれらを常に使用すべきだと説きます。ただし、どちらのソリューションも優れたIMOです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top