2010-02-05 3 views
1

Скажем, у меня есть класс с членами профсоюза в нем:Присвоение союзов членов

class ClassX { 
public: 
    union { 
    StructA * A; 
    StructB * B; 
    }; 
    } 

Если у меня есть указатели x1 и x2 для различных объектов ClassX, делает это:

x1->A = x2->A; 

Есть аналогичный эффект:

x1->B = x2->B; 

? Благодарю.

+1

Это то, что ожидается. Объединение означает, что A и B занимают одно и то же место в памяти. – kenny

ответ

5

Для большинства практических целей, в большинстве реализаций эти два утверждения будут иметь такой же эффект, однако это не гарантируется. Если член, который вы читаете из союза, не является последним членом, который был навязан профсоюзу, поведение программы не определено.

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

0

Они не имеют такого же эффекта, если только StructA и StructB не имеют одинакового размера. Первая строка, которую вы разместили, копирует всю память, занятую x2->A, в x1->A, а вторая делает то же самое для B. A и B занимают перекрывающуюся область памяти, но могут быть разных размеров, и в этом случае оба утверждения не эквивалентны.

+0

Это структурные указатели, а не структуры, которые копируются. Довольно точно, что они имеют одинаковый размер независимо от содержимого базовых структур. –

+0

x2-> A - указатель. Это, вероятно, будет работать, если указатели не имеют разных размеров или требований к выравниванию. Реализации для реализаций используются разные представления указателей для разных структур. –

0

Операции должны быть идентичными. Но это может быть не так, если вы перегрузили оператор присваивания для любого из этих двух типов указателей.

+1

Ум ... вы не можете перегрузить назначение указателей. Даже если вы перегрузили назначение для 'StructA', это все равно будет сборкой в ​​назначении указателей и не связано с оператором присваивания перегрузки StructA' StructA * a; StructA * b; a = b; ' –

+0

Вы правы - назначение может быть перегружено только как функция-член. Я как-то воображал, что вы можете написать «A * operator = (A *, B *)»; –

2

Какой ответ вы ожидаете?

Формальный и педантичный? Если это так, то ответа на этот вопрос просто нет. Язык C++ дает вам официальную возможность сравнить эффекты этих двух назначений. Если вы назначили ClassX::A, вы можете читать только ClassX::A, а не ClassX::B. Если вы назначили ClassX::B, вы можете читать только ClassX::B, а не ClassX::A. Другими словами, нет веских причин даже заботиться о том, являются ли эффекты одинаковыми или нет. Язык просто не позволяет вам заботиться об этом. Если ваш код каким-то образом опирается на него, то его поведение не определено, насколько это касается формального C++.

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

+0

Извините, что набросился на вас, но такие заявления, как «Какой ответ вы ожидаете?» кажутся бесполезно воспалительными, и это приведет к игнорированию даже хорошей информации. Если я заметлю, что сообщение изменится к лучшему, я подниму его. – Sqeaky

1

C++1x Standard Draft, Section 9.5.1

В союзе, в лучшем случае один из данных члены могут быть активны в любое время, то есть, значение, самое большее, один из членов данных могут храниться в Объединение в любое время. [Примечание: одна специальная гарантия предназначена для упрощения использования объединений: если POD-соединение содержит несколько POD-структур, которые имеют общую начальную последовательность (класс.mem), и если объект этого типа POD-union содержит одну из POD-структур , то разрешено проверять общую начальную последовательность любого из элементов структуры POD; см. класс.mem. ]

Обратите внимание на специальную гарантию.

+0

Специальная гарантия здесь даже не применяется. Никаких структур в этом союзе. – AnT

+0

Да @ AndreyT, но я считаю, что это исключение, которое все еще стоит знать. Не потому, что это полезно, а потому, что это заставляет вас выиграть аргументы юристов на языках;) [вы можете сказать «да, подождите, есть исключение»] –

Смежные вопросы