У меня есть некоторые вопросы о неограниченных союзах и их применении на практике. Давайте предположим, что у меня есть следующий код:Неограниченное объединение на практике
struct MyStruct
{
MyStruct(const std::vector<int>& a) : array(a), type(ARRAY)
{}
MyStruct(bool b) : boolean(b), type(BOOL)
{}
MyStruct(const MyStruct& ms) : type(ms.type)
{
if (type == ARRAY)
new (&array) std::vector<int>(ms.array);
else
boolean = ms.boolean;
}
MyStruct& operator=(const MyStruct& ms)
{
if (&ms != this) {
if (type == ARRAY)
array.~vector<int>(); // EDIT(2)
if (ms.type == ARRAY)
new (&array) std::vector<int>(ms.array);
else
boolean = ms.boolean;
type = ms.type;
}
return *this;
}
~MyStruct()
{
if (type == ARRAY)
array.~vector<int>();
}
union {
std::vector<int> array;
bool boolean;
};
enum {ARRAY, BOOL} type;
};
- этот код действителен :)?
- Нужно явно вызывать деструктор вектора каждый раз, когда мы используем логическое значение (как указано здесь http://cpp11standard.blogspot.com/2012/11/c11-standard-explained-1-unrestricted.html)
- Почему размещение нового требуется вместо того, чтобы просто делать что-то вроде «массив = ms.array»?
EDIT:
- Да, он компилирует
- «Члены, объявленные внутри анонимные объединения фактически члены содержащего класса, и можно инициализировать в конструкторе объемлющего класса.» (C++11 anonymous union with non-trivial members)
- Добавление явных деструкторов, как предложено, приводит к SIGSEV с г ++ 4.8/Clang 4,2
Союзы иногда используются, чтобы подорвать тип системы - пиннинг типа.В этом случае вы не будете уничтожать «вектор» перед чтением/записью 'bool', но стандарт не определяет (и не может) определить, что это означает - эффект зависит от деталей платформы. Вы, вероятно, не сделали бы этого с 'vector' в любом случае - возможно, с массивом char, чтобы увидеть байты. Если вы не пишите, вы можете только зачитывать, что было написано в последний раз (или ожидать повреждения данных), и вы должны удалить (уничтожить) все, что уже есть в союзе, прежде чем писать что-то еще (или ожидать утечки памяти/ресурсов) , – Steve314