Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Объединения






В С++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 содержит конструктор по умолчанию,

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






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.