Frage

In C ++, habe ich eine Klasse, die eine anonyme bitfield Struktur enthält. Ich mag es auf Null initialisieren, ohne schreiben, manuell alle Felder aus.

Ich kann mir vorstellen, die Initialisierung an drei Stellen setzen:

  1. Erstellen Sie einen Konstruktor in der bitfield
  2. Null out in der Initialisierungsliste des Konstruktor für die Klasse enthält,
  3. Null aus in dem Körper des Konstruktor für die Klasse enthält,

Dieses bitfield hat viele Felder, und ich möchte lieber nicht sie alle aufzuzählen.

Zum Beispiel finden Sie in den folgenden Code:

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

Ist eine dieser vorzuziehen? Oder gibt es etwas anderes fehlt ich?

Edit: Basierend auf der akzeptierte Antwort unten (von Ferruccio) ich auf dieser Lösung angesiedelt:

class Big {
    // ...

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

    // ...
}
War es hilfreich?

Lösung

Sie können immer tun dies in Ihrem Konstruktor:

memset(&bflag, 0, sizeof bflag);

Andere Tipps

Union die bitfield Struktur mit etwas einfacher zu initialisieren auf 0.

Sie können eine Vereinigung verwenden, aber das ist eine zusätzliche Dereferenzierungsebene hinzufügen würde, wenn die Felder zugreifen:

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

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

MSVC ermöglicht anonyme Strukturen innerhalb der Gewerkschaften (siehe beispielsweise die Definition von D3DMATRIX in <d3d9.h>), aber dies ist eine Nicht-Standard-C ++ Erweiterung, die Sie vermeiden, verwenden sollten, wenn Sie können.

Als beiseite, wenn Sie die bitfield müssen einige Legacy-Code zu verbinden, sollten Sie sie nicht benutzen. Sie sind von Natur aus nicht portierbar und ineffizient.

Ihre Verwendung eines funktionsähnlichen initializer (markiert mit „Kann ich Null bflag hier?“) Ist zu 100% ausreichend POD Struktur mit 0 Werten zu initialisieren.

Wenn Sie nicht wissen, dass Ihr Compiler in dieser Hinsicht gebrochen ist, eine zusätzliche Initialisierung der Mitglieder tun, ist es zweimal für keinen Nutzen zu initialisieren.

EDIT:. Nur für 'Spaß' Ich habe gerade überprüft diese mit VS2005, VS2008, GCC 3.4.4, GCC 4.2 und Borland C ++ 5.5.1 ... nur Borland C ++ 5.5.1 wird es falsch

Und ich sage ‚falsch‘, weil es mir scheint, dass 8,5 und 8.5.1 der Norm bedeuten, dass die funktionsähnlichen initializer sollte die POD-Struktur Null-init.

könnten Sie die interne Speicherkapazität Zeromemory oder Memset im Konstruktor auf diese Weise sauberer ist es aussehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top