Можно ли соединить несколько объектов в союз? - PullRequest
11 голосов
/ 12 апреля 2009

Что если у меня есть это:

union{
    vector<int> intVec ;
    vector<float> floatVec ;
    vector<double> doubleVec ;
} ;

Конечно, я буду использовать только один из 3 векторов. Но ... что происходит, когда все 3 вектора построены ??
Могут ли конструкторы из 3 векторов мешать друг другу? (поскольку 3 из них находятся в одном и том же адресе памяти)

Спасибо.

Ответы [ 5 ]

16 голосов
/ 12 апреля 2009

Текущий стандарт C ++ не допускает не-POD типы внутри союзов. Вы получите эту ошибку компилятора от gcc:

error: member ‘std::vector<int, std::allocator<int> >
<anonymous union>::i’ with constructor not allowed in union
error: member ‘std::vector<int, std::allocator<int> >
<anonymous union>::i’ with destructor not allowed in union

Новый стандарт C ++ ( C ++ 0x ) предлагает неограниченные объединения , но он добавляет еще больше ошибок времени жизни объекта в C ++ .

9 голосов
/ 12 апреля 2009

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

Вы можете использовать boost::variant как безопасную альтернативу профсоюзам C. См. Документацию на boost.org . Однако вы можете пересмотреть свой дизайн и использовать вместо этого полиморфизм. Конечно, зависит от того, чего вы пытаетесь достичь.

2 голосов
/ 12 апреля 2009

Могут ли конструкторы трех векторов мешать друг другу? (поскольку 3 из них находятся в одном и том же адресе памяти)

Стандарт C ++ не позволяет вашей программе, так что это (в лучшем случае!) Определяется реализацией того, что происходит.

Если, скажем, ваша реализация вызывает все три стандартных конструктора, и все они выделяют память, и сохраняет указатель на вновь выделенное пространство, у вас есть утечка памяти (первые два выделения перезаписываются третьим). 1007 *

Если все деструкторы вызываются и все они освобождают «свою» память, вы будете делать двойное освобождение (тройное, фактически); это может повредить структуру данных распределения, что является плохой вещью. Будьте счастливы, если рухнете, потому что отладить намного сложнее, если вы этого не сделаете.

Я думаю, что эти проблемы могут быть , почему стандарт не позволяет этого.

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

2 голосов
/ 12 апреля 2009

Из стандарта C ++, раздел 9.5:

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

Здесь, для «нетривиального» читать «полезный»: -)

1 голос
/ 12 апреля 2009

Возможно, вы захотите взглянуть на Boost.Variant , который может содержать одно значение различных типов.

...