Pergunta

Se eu quisesse representam estados ou opções ou algo semelhante usando "bandeiras" binários para que eu pudesse passá-los e armazená-los para um objeto como OPTION1 | OPTION2 onde OPTION1 é 0001 e OPTION2 é 0010, de modo que o que se passou é 0011, representando uma mistura das opções.

Como eu poderia fazer isso em C ++? Eu estava pensando em algo como

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

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

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

Mas, em seguida, idealmente, doSomething sabe como interpretar a opção dada.

Am I no caminho certo? Existe uma maneira melhor?

Atualizar

E eu não teria que definir uma Option para cada combinação possível, também?

Foi útil?

Solução

Esta é uma forma comum estas coisas são feitas. doSomething pode usar o operador bit a bit and para ver se uma opção for selecionada:

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

Como alternativa, você pode considerar o uso campos de bits :

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

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

Outras dicas

Isso seria a maneira que eu faria isso. No entanto, existem muitos truques que você pode usar para fazer a enumeração um pouco mais legível:

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

O que é mais, você vai precisar especificar operadores bit a bit para sua enumeração. Considere algo como utilitários enum_ops do ASL para ajudar com isso.

Sua digno que a forma como as pessoas costumam usar tais bandeiras é definir a função da seguinte forma:

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

tudo o resto vai funcionar exatamente como você quiser:)

A outra maneira é criar seu próprio "Flags" classe. Então você tem um par de funções como segue na classe:

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

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

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

ou até mesmo sobrecarregar os operadores para fazer exatamente como você gostaria por exemplo:

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

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

e assim por diante.

Você pode querer verificar o stl bitset . Algumas pessoas pregam que você deve sempre usar aqueles em vez de bitflags de estilo C. No entanto, ambas as soluções são muito bem IMO.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top