Pregunta

Si quisiera representar estados u opciones o algo similar usando binarios " flags " para poder pasarlos y almacenarlos en un objeto como OPTION1 | OPTION2 donde OPTION1 es 0001 y OPTION2 es 0010, de modo que lo que se pasa es 0011, que representa una combinación de las opciones.

¿Cómo haría esto en C ++? Estaba pensando en algo como

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

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

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

Pero idealmente, doSomething sabe cómo interpretar la Opción dada.

¿Estoy en el camino correcto? ¿Hay alguna manera mejor?

Actualizar

¿Y no tendría que definir también una Option para cada combinación posible?

¿Fue útil?

Solución

Esta es una forma común en que se hacen estas cosas. doSomething puede usar el operador bitcode y para ver si una opción está seleccionada:

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

Como alternativa, puede considerar el uso de 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;

Otros consejos

Esa sería la forma en que lo haría. Sin embargo, hay muchos trucos que puedes usar para hacer que la enumeración sea un poco más legible:

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

Además, deberá especificar operadores bitwise para su enumeración. Considere algo como las utilidades enum_ops de ASL para ayudar con esto.

Vale la pena señalar que la forma en que las personas suelen usar estos indicadores es definir la función de la siguiente manera:

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

todo lo demás funcionará exactamente como quieres :)

La otra forma es crear su propio " Banderas " clase. Luego tienes un par de funciones como las siguientes en la clase:

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

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

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

o incluso sobrecargue a los operadores para que hagan exactamente lo que le gustaría, por ejemplo:

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

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

y así sucesivamente.

Es posible que desee consultar stl bitset . Algunas personas predicarían que siempre deberías usar esos en lugar de bitflags estilo C. Sin embargo, ambas soluciones son buenas de la OMI.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top