Pregunta

En C ++, tengo una clase que contiene una estructura de campo de bits anónima. Quiero inicializarlo a cero sin tener que escribir manualmente todos los campos.

Me imagino poniendo la inicialización en tres lugares:

  1. Crear un constructor en el campo de bits
  2. Poner a cero en la lista de inicializadores del constructor para la clase que contiene
  3. Poner a cero en el cuerpo del constructor para la clase que contiene

Este campo de bits tiene muchos campos, y prefiero no enumerarlos todos.

Por ejemplo, vea el siguiente código:

class Big {
    public:
        Big();

        // Bitfield struct
        struct bflag_struct {
            unsigned int field1 : 1;
            unsigned int field2 : 2;
            unsigned int field3 : 1;
            // ...
            unsigned int field20 : 1;
            // bflag_struct(); <--- Here?
        } bflag;

        unsigned int integer_member;
        Big         *pointer_member;
}

Big::Big()
  : bflag(),             // <--- Can I zero bflag here?
    integer_member(0),
    pointer_member(NULL)
{
    // Or here?
}

¿Es preferible uno de estos? ¿O hay algo más que me estoy perdiendo?

Editar: Basado en la respuesta aceptada a continuación (por Ferruccio) Me decidí por esta solución:

class Big {
    // ...

    struct bflag_struct {
        unsigned int field 1 : 1;
        // ...
        bflag_struct() { memset(this, 0, sizeof *this); };
    }

    // ...
}
¿Fue útil?

Solución

Siempre puedes hacer esto en tu constructor:

memset(&bflag, 0, sizeof bflag);

Otros consejos

Unión de la estructura de campo de bits con algo más fácil de inicializar a 0.

Podría usar una unión, aunque eso agregaría un nivel adicional de indirección al acceder a los campos:

class Big {
    union {
        struct {
            unsigned int field1 : 1;
            ...
        } fields;
        unsigned int all_fields;
    };
    ...
};

Big::Big()
  : all_fields(0),
    ...
{
    ...
}

MSVC permite estructuras anónimas dentro de las uniones (consulte, por ejemplo, la definición de D3DMATRIX en <d3d9.h>), pero esta es una extensión de C ++ no estándar que debe evitar usar si puede.

Como comentario aparte, a menos que necesite el campo de bits para interactuar con algún código heredado, no debe usarlos. Son inherentemente inportables e ineficientes.

Su uso de un inicializador similar a una función (marcado " ¿Puedo poner a cero bflag aquí? ") es 100% suficiente para inicializar su estructura POD con 0 valores.

A menos que sepa que su compilador está roto a este respecto, hacer cualquier inicialización adicional de esos miembros es inicializarlo dos veces sin ningún beneficio.

EDITAR: Solo por "diversión" Acabo de comprobar esto con VS2005, VS2008, GCC 3.4.4, GCC 4.2 y Borland C ++ 5.5.1 ... solo Borland C ++ 5.5.1 se equivoca.

Y digo 'incorrecto' porque me parece que 8.5 y 8.5.1 del estándar implican que el inicializador de función debería poner a cero la estructura POD.

puede poner a cero la memoria usando ZeroMemory o memset en el constructor de esa manera se ve más limpia.

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