C ++ Union, Struct, тип члена - PullRequest
5 голосов
/ 18 июня 2010

Если у меня есть класс:

class Odp
{
    int i;
    int b;
    union
    {
         long f;
         struct
         {
               WCHAR* pwszFoo;
               HRESULT hr;
         };
    };

}

Объединение означает, что из всех перечисленных значений он может принимать только одно из этих значений одновременно?Как это работает с точки зрения доступа к этим переменным?Как бы я получил доступ к hr напрямую?Если я установлю hr, что произойдет, если я попытаюсь получить доступ к f?

Ответы [ 5 ]

8 голосов
/ 18 июня 2010

Это очень опасная область в стандарте C ++ - в основном экземпляр объединения, в соответствии со стандартом, может обрабатываться только в одно время, как если бы он содержал один «активный» член - последний записанный в него. Итак:

union U {
   int a;
   char c;
};

тогда:

U u;
u.a = 1;
int n = u.a;
u.c = 2;
char c = u.c;

в порядке, но:

U u;
u.a = 1;
char c = u.c;

нет. Однако существует огромный объем существующего кода, который говорит, что оба в порядке. и ни в одном, ни в любом случае не будет выдано исключение для «недействительного» доступа. Язык C ++ использует исключения исключительно (!) Экономно.

По сути, если вы обнаруживаете, что в своем коде C ++ используете союзы для работы с чем угодно, кроме библиотек C, что-то не так.

4 голосов
/ 18 июня 2010

Каждый раз, когда вы устанавливаете (записываете) в член союза, вы, по сути, делаете его «активным».Вам разрешено только читать в настоящее время активный член союза.Это означает, что вы должны каким-то образом помнить, какой член активен в каждый момент времени.

Попытка доступа к неактивному члену объединения приводит к неопределенному поведению.

Имейте в виду такжечто ваш код не является допустимым C ++.В C ++ нет такой вещи, как «анонимная структура».Ваш член структуры должен иметь имя.Если ваш компилятор принимает его, это просто нестандартное расширение, поддерживаемое вашим конкретным компилятором.

2 голосов
/ 18 июня 2010

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

Попробуйте использовать следующее для доступа hr:

union a;
a.hr = NULL;
1 голос
/ 18 июня 2010

Это просто означает, что вы можете получить доступ к той же памяти, что и long, или struct.

Для доступа hr:

Odp o1;
o1.hr;

Интересная ссылка: http://www.cplusplus.com/forum/general/18816/

0 голосов
/ 15 сентября 2016

Попытка доступа к «f» даст вам некоторый результат. Вероятно, это будет представление другого члена union как тип данных «f», т. Е. В этом случае вы, скорее всего, будете читать частичное или полное содержимое «pwszFoo», представленного как «длинный» тип данных. Общая концепция проста - члены профсоюза находятся в одном месте в памяти.

...