Объединения

В С++98 (как и в более ранних версиях языка С++), члены с пользовательским конструктором, деструктором или оператором присваивания не могли использоваться в объединениях (union):

union U {

Int m1;

//ошибка (глупая): complex содержит конструктор

complex m2;

//ошибка (не глупая): string обладает сложным инвариантом

//поддерживается ctor, copy и dtor

String m3;

};

В частности:

//какой конструктор вызывать (и вызывать ли вообще)?

U u;

//присваивание члену с типом int

u.m1 = 1;

//беда: чтение строки

string s = u.m3;

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

В С++11, ограничения, накладываемые на объединения, изменены для поддержки большего количества типов; в частности, членам объединений позволяется иметь конструкторы и деструкторы. Стандарт также добавляет ограничения, чтобы уменьшить количество ошибок в наиболее гибких вариантах использования объединений, поощряя создание размеченных объединений (discriminated unions).

Типы членов объединений ограничены следующим образом:

Например:

union U1 {

Int m1;

complex m2; //ok

};

union U2 {

Int m1;

string m3; //ok

};

Может показаться, что это решение будет приводить к ошибкам, но благодаря новым ограничениям это не так. В частности:

//ok

U1 u;

//ok: присваивание члена типа complex

u.m2 = {1,2};

//ошибка: деструктор string приводит к удалению деструктора U

U2 u2;

//ошибка: конструктор копирования string приводит к удалению

//конструктора копирования U

U2 u3 = u2;

По сути, объединение U2 является бесполезным, пока оно не будет включено в структуру, которая отслеживает, какой из членов объединения используется в данный момент. Т.е. для создания размеченных объединений типа:

//Три альтернативные реализации, использующих объединения

class Widget {

private:

//дискриминант

enum class Tag { point, number, text } type;

//представление

union {

//point содержит конструктор

Point p;

Int i;

//string содержит конструктор по умолчанию,



//операции копирования и деструктор


6960809829246192.html
6960882736319999.html
    PR.RU™