Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Объединения
В С++98 (как и в более ранних версиях языка С++), члены с пользовательским конструктором, деструктором или оператором присваивания не могли использоваться в объединениях (union): union U { Int m1; // ошибка (глупая): complex содержит конструктор complex< double> 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< double> 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 содержит конструктор по умолчанию, // операции копирования и деструктор
|