Hva er den beste måten å klargjøre en bitfield struct i C ++?

stemmer
4

I C ++, jeg har en klasse som inneholder en anonym bitfield struct. Jeg ønsker å initialisere den til null uten å måtte manuelt skrive ut alle felt.

Jeg kan tenke meg å sette initialisering på tre steder:

  1. Lag en konstruktør i bitfield
  2. Null ut i initializer listen over konstruktøren for inneholder klasse
  3. Null ut i kroppen av konstruktøren for inneholder klasse

Dette bitfield har mange felt, og jeg vil heller ikke liste dem alle.

For eksempel se følgende kode:

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?
}

Er en av disse å foretrekke? Eller er det noe annet jeg mangler?

Edit: Basert på den aksepterte svaret nedenfor (fra Ferruccio) Jeg avgjort på denne løsningen:

class Big {
    // ...

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

    // ...
}
Publisert på 04/03/2009 klokken 20:51
kilden bruker
På andre språk...                            


7 svar

stemmer
9

Union bitfield struct med noe lettere å initial til 0.

Svarte 04/03/2009 kl. 20:56
kilden bruker

stemmer
9

Du kan alltid gjøre dette i konstruktøren:

memset(&bflag, 0, sizeof bflag);
Svarte 04/03/2009 kl. 20:54
kilden bruker

stemmer
6

Du kan bruke en union, selv om det ville legge en ekstra indirekte nivå ved tilgang feltene:

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

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

MSVC tillater anonyme structs innsiden av fagforeninger (se f.eks definisjonen av D3DMATRIXi <d3d9.h>), men dette er en ikke-standard C ++ utvidelse som du bør unngå å bruke hvis du kan.

Svarte 04/03/2009 kl. 20:56
kilden bruker

stemmer
3

Som en side, med mindre du trenger bitfield til grensesnittet til noen arven kode, bør du ikke bruke dem. De er er iboende unportable og ineffektiv.

Svarte 04/03/2009 kl. 20:57
kilden bruker

stemmer
2

Din bruk av en funksjon-lignende initializer (merket "Kan jeg null bflag her?") Er 100% tilstrekkelig til å initialisere din POD struct med 0-verdier.

Med mindre du vet at kompilatoren er brutt i denne forbindelse, gjør noen ekstra initialisering av disse medlemmene er initialisert den to ganger for ingen nytte.

EDIT: Bare for 'moro' Jeg sjekket dette med VS2005, VS2008, GCC 3.4.4, GCC 4.2, og Borland C ++ 5.5.1 ... bare Borland C ++ 5.5.1 blir det galt.

Og jeg sier 'feil' fordi det virker for meg at 8.5 og 8.5.1 i standarden innebærer at funksjonen lignende initializer bør null-init POD struct.

Svarte 05/03/2009 kl. 15:43
kilden bruker

stemmer
0

BTW C ++ 20 bærere Initialisering av bitfields i klassedefinisjon f.eks

class ... {
   int foo : 1 {};
}

gcc med -std = c ++ 2a for å muliggjøre

Svarte 01/09/2019 kl. 01:03
kilden bruker

stemmer
0

du kan nullstille minnet med ZeroMemory eller memset i konstruktøren slik det ser er renere.

Svarte 04/03/2009 kl. 20:55
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more