Инициализация объединения с нетривиальным конструктором

55
задан Bill the Lizard 16 August 2010 в 02:32
поделиться

5 ответов

Вопрос 1: Конструкторы по умолчанию действительно инициализируют участников POD к 0 согласно стандарту C++. См. заключенный в кавычки текст ниже.

Вопрос 2: Если конструктор должен быть определен в базовом классе, то тот класс не может быть частью объединения.

Наконец, можно предоставить конструктору для объединения:

union U 
{
   A a;
   B b;

   U() { memset( this, 0, sizeof( U ) ); }
};

Для Q1:

От C++ 03, 12.1 Конструкторов, pg 190

неявно определенный конструктор по умолчанию выполняет набор инициализаций класса, который был бы выполнен написанным пользователем конструктором по умолчанию для того класса с пустым списком инициализатора мадам (12.6.2) и пустым телом функции.

От C++ 03, 8.5 Инициализаторов, pg 145

Для установки по умолчанию - инициализирует объект средств типа T:

  • , если T является типом класса не-POD (пункт 9), конструктора по умолчанию для T называют (и инициализация плохо формируется, если T не имеет никакого доступного конструктора по умолчанию);
  • , если T является типом массива, каждый элемент инициализируется значением по умолчанию;
  • иначе, объект инициализируется нулем .

Для обнуления - инициализируют объект средств типа T:

  • , если T является скалярным типом (3.9), объект установлен на значение 0 (нуль), преобразованный в T;
  • , если T является не состоящим в профсоюзе типом класса, каждый не, статический элемент данных и каждый подобъект базового класса инициализируются нулем ;
  • , если T является типом объединения, object’s, сначала названный элементом данных, инициализируется нулем;
  • , если T является типом массива, каждый элемент инициализируется нулем;
  • , если T является ссылочным типом, никакая инициализация не выполняется.

Для Q2:

От C++ 03, 12.1 Конструкторов, pg 190

конструктор А тривиален, если это - неявно объявленный конструктор по умолчанию и если:

  • его класс не имеет никаких виртуальных функций (10.3) и никаких виртуальных базовых классов (10.1), и
  • , все прямые базовые классы его класса имеют тривиальных конструкторов, и
  • для всех нестатических элементов данных его класса, которые имеют тип класса (или выстройте этого), каждый такой класс имеет тривиального конструктора

От C++ 03, 9.5 Объединений, pg 162

, объединение А может иметь функции членства (включая конструкторов и деструкторы), но не виртуальное (10.3) функции. Объединение не должно иметь базовых классов. Объединение не должно использоваться в качестве базового класса. Объект класса с нетривиальным конструктором (12.1), нетривиальный конструктор копии (12.8), нетривиальный деструктор (12.4) или нетривиальный оператор присваивания копии (13.5.3, 12.8) не может быть членом объединения, ни может массив таких объектов

47
ответ дан David Rodríguez - dribeas 7 November 2019 в 07:24
поделиться

У членов профсоюза AFAIK не может быть конструкторов или деструкторов.

Вопрос 1: нет, нет такой гарантии. Любой участник POD не в списке инициализации конструктора инициализируется значением по умолчанию, но это с конструктором, которого Вы определяете, и имеет список инициализатора. Если Вы не определите конструктора, или Вы определяете конструктора без списка инициализатора и пустого тела, участники POD не будут инициализированы.

участники неPOD будут всегда создаваться с помощью их конструктора по умолчанию, который, если синтезируется, снова не инициализировал бы участников POD. Учитывая, что у членов профсоюза не может быть конструкторов, Вам в значительной степени гарантировали бы это, участники POD структур в объединении не будут инициализированы.

Вопрос 2: можно всегда инициализировать структуры/объединения как так:

struct foo
{
    int a;
    int b;
};

union bar
{
    int a;
    foo f;
};

bar b = { 0 };
3
ответ дан 7 November 2019 в 07:24
поделиться

Как упомянуто в комментарии Greg Rogers к сообщение unwesen, можно дать объединению конструктора (и деструктор, если Вы желаете):

struct foo
{
    int a;
    int b;
};

union bar
{
    bar() { memset(this, 0, sizeof(*this)); }

    int a;
    foo f;
};
2
ответ дан Community 7 November 2019 в 07:24
поделиться

Можно ли сделать что-то вроде этого?

class Outer
{
public:
    Outer()
    {
        memset(&inner_, 0, sizeof(inner_));
    }
private:
    union Inner
    {
        int qty_;
        double price_;
    } inner_;
};

... или возможно что-то вроде этого?

union MyUnion
{
    int qty_;
    double price_;
};

void someFunction()
{
    MyUnion u = {0};
}
0
ответ дан John Dibling 7 November 2019 в 07:24
поделиться

Необходимо будет ожидать C++ 0x, чтобы поддерживаться компиляторами для получения этого. До тех пор, извините.

-1
ответ дан Michel 7 November 2019 в 07:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: