Каков наилучший способ инициализации структуры битового поля в C ++?

StackOverflow https://stackoverflow.com/questions/612374

Вопрос

В C ++ у меня есть класс, который содержит анонимную структуру битовых полей. Я хочу инициализировать его нулем без необходимости выписывать все поля вручную.

Я могу представить инициализацию в трех местах:

<Ол>
  • Создать конструктор в битовом поле
  • Обнулить список инициализатора конструктора для содержащего класса
  • Обнуление в теле конструктора для содержащего класса
  • В этом битовом поле много полей, и я бы не стал перечислять их все.

    Например, см. следующий код:

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

    Является ли один из них предпочтительным? Или я что-то пропустил?

    Изменить: на основе принятого ответа ниже (Ферруччо) я остановился на этом решении:

    class Big {
        // ...
    
        struct bflag_struct {
            unsigned int field 1 : 1;
            // ...
            bflag_struct() { memset(this, 0, sizeof *this); };
        }
    
        // ...
    }
    
    Это было полезно?

    Решение

    Вы всегда можете сделать это в своем конструкторе:

    memset(&bflag, 0, sizeof bflag);
    

    Другие советы

    Объедините структуру битового поля с чем-то более простым для инициализации в 0.

    Вы могли бы использовать объединение, хотя это добавило бы дополнительный уровень косвенности при доступе к полям:

    class Big {
        union {
            struct {
                unsigned int field1 : 1;
                ...
            } fields;
            unsigned int all_fields;
        };
        ...
    };
    
    Big::Big()
      : all_fields(0),
        ...
    {
        ...
    }
    

    MSVC допускает анонимные структуры внутри союзов (см., например, определение D3DMATRIX в <d3d9.h>), но это нестандартное расширение C ++, которое следует избегать, если вы можете.

    Кроме того, если вам не нужно битовое поле для взаимодействия с каким-либо устаревшим кодом, вы не должны их использовать. Они по своей природе непереносимы и неэффективны.

    Использование функционально-подобного инициализатора (помеченного " можно ли здесь обнулить bflag? ") на 100% достаточно для инициализации структуры POD с 0 значениями.

    Если вы не знаете, что ваш компилятор не работает в этом отношении, любая дополнительная инициализация этих членов инициализирует его дважды без какой-либо выгоды.

    РЕДАКТИРОВАТЬ: Просто для удовольствия, я только что проверил это с VS2005, VS2008, GCC 3.4.4, GCC 4.2 и Borland C ++ 5.5.1 ... только Borland C ++ 5.5.1 ошибается.

    И я говорю «неправильно», потому что мне кажется, что 8.5 и 8.5.1 стандарта подразумевают, что подобный функции инициализатор должен начинать с нуля структуру POD.

    вы можете обнулить память, используя ZeroMemory или memset в конструкторе, чтобы она выглядела чище.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top