Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.67
Elfenlide
23 / 23 / 1
Регистрация: 15.04.2012
Сообщений: 183
#1

Union - Объединения - C++

21.09.2012, 17:49. Просмотров 2312. Ответов 21
Метки нет (Все метки)

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

Что-нибудь более реальное к жизни что ли хотелось бы увидеть. Ну как минимум это union и структуры, или классы.
И если кто видел книгу в которой доходчиво рассказывается про union дайте пожалуйста название этой книги.
Спасибо!
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.09.2012, 17:49
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Union - Объединения (C++):

Объединения (union) - C++
Имеется задача: (Нужно выполнить решения, используя объединения.) Ввести с клавиатуры два произвольных символа. Составить число типа...

Тип объединения union - C++
Цель: Создайте объект на основе типа объединения union. Докажите, что члены объекта располагаются по одному адресу, а функции-члены - по...

Union - C++
Человеки привет =) Скажите пожалуйста для чего используются union в С++?

Union - C++
Возник вопрос про объединения. В книгах я встречал лишь случай, когда размер одного из полей больше или равен сумме размеров остальных....

Union - C++
Здравствуйте! Я уже задавал тут вопрос, как использовать union, и сейчас столкнулся с проблемой: Есть 3 файла и заголовочный файл -...

Union-объеденения - C++
Добрый день. Почему при выводе cout << "u2 как целое: "; //выводит число 22872? cout << u2.i << '\n'; // ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Invader_Zim
Twilight Parasite
153 / 149 / 2
Регистрация: 21.07.2011
Сообщений: 908
21.09.2012, 17:52 #2
Elfenlide, K&R! так как юнионы, энумы и структуры это наследие няшного Си!
0
Infinity3000
1058 / 577 / 24
Регистрация: 03.12.2009
Сообщений: 1,255
21.09.2012, 17:54 #3
ОБЪЕДИНЕНИЯ
0
Elfenlide
23 / 23 / 1
Регистрация: 15.04.2012
Сообщений: 183
21.09.2012, 18:18  [ТС] #4
Цитата Сообщение от Invader_Zim Посмотреть сообщение
Elfenlide, K&R! так как юнионы, энумы и структуры это наследие няшного Си!
K&R! - это как понимать?)
Дайте нормальную книгу или может сайт с хорошими примерами.
Ссылка что дали выше ,я там был, и совсем не понимаю зачем что и почему.....как бы понятно, что можно выводить в разных типах одно значение, но неужели юнион используют только для того чтобы
выполнять задачи подобные этой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    #include <iostream.h>
 
    void main(void)
 
    {
       union distance
 
       {
          int miles;
          long meters;
       } walk;
 
       walk.miles = 5;
       cout << "Пройденное расстояние в милях " << walk.miles << endl;
       walk.meters = 10000;
       cout << "Пройденное расстояние в метрах " << walk.meters << endl;
    }
Расскажу в чём дело, у меня в универе 2 курс есть предмет ППвИС, и дали мне первую лабу реализовать класс Set и основные операции над множествами, не использую STL, я сделал всё кроме одного пункта: Множеств может являться элементом другого множества.
Как это сделать я не представляю себе. Препод сказал используй "Объединения Union", я посмотрел что там к чему, и ничего не понял, препод мне объяснил тоже что и на сайт указанном выше, хотя это мне понятно. Непонятно как юнион в моей ситуации может помочь. он сказал использовать можно юнион и массив структур.. дал небольшой фрагмент который от руки набросал за минуту, сказал пару умных слов и я так и ничего не понял...ну, кроме мелочей которые итак ясны....
это то что он мне написал:
C++
1
2
3
4
5
6
7
8
union element{
char* el;
Set* s;
}
struct Set_Element{
enum ElType{ATOM,SET};
int type;
Element el;
откуда тут Set* s; мне непонятно....ибо set это должно быть либо класс либо структура как я понимаю....ну и что тут к чему...не совсем понятно....зачем тут перечисление тоже не понял....на мои вопросы он ответил видимо слишком умно, для моих знаний\
0
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
21.09.2012, 18:19 #5
Invader_Zim, Ага, только вот union в C++11 вышел далеко за рамки данного наследия.
0
Invader_Zim
Twilight Parasite
153 / 149 / 2
Регистрация: 21.07.2011
Сообщений: 908
21.09.2012, 18:30 #6
ForEveR, что не использую, о том не говорю. Времени с новым стандартом разобраться ,к сожалению, нет.
0
Elfenlide
23 / 23 / 1
Регистрация: 15.04.2012
Сообщений: 183
21.09.2012, 21:01  [ТС] #7
Цитата Сообщение от ForEveR Посмотреть сообщение
Invader_Zim, Ага, только вот union в C++11 вышел далеко за рамки данного наследия.
Это всё замечательно,но может кто-нибудь мне сможет всё-таки объяснить, а-то разговоров об этом много а что это и зачем, непонятно
0
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
21.09.2012, 21:16 #8
Окей, суть в чём: юнион позволяет хранить несколько величин (в данном случае величины типов нормальный-элемент-множества и множество-как-элемент-множества) в одном куске памяти. То есть одну и ту же переменную юнион-типа можно трактовать и как один из хранимых типов, и как другой.

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

Идею вы поняли правильно (шаблонами не гружу):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
struct SetElement {
  enum { ATOM, SET } type; // токен типа, содержащий тип текущих хранимых данных
  
  // Собсно данные: или атом, или множество. Фишка в том, что можно хранить или
  // множество, или атом. Если достать что-то другое, то получим мусор и вообще капец.
  // Всё из-за того, что хранятся они в одном и том же месте памяти.
  //
  // Хранить сразу значения или указатели на них, решайте сами, тут однозначно не скажешь.
  union {
    char atom;
    Set set;
  };
 
  SetElement(char value)
  {
    atom = value;
    type = ATOM;
  }
 
  SetElement(const Set &value)
  {
    set = value;
    type = SET;
  }
 
  SetElement& operator=(char value)
  {
    atom = value;
    type = ATOM;
    return *this;
  }
 
  SetElement& operator=(const Set &value)
  {
    set = value;
    type = SET;
    return *this;
  }
 
  bool operator==(const SetElement &other)
  {
    if (this->type != other.type) {
      return false;
    }
    else {
      if (this->type == ATOM) {
        return this->atom == other.atom;
      }
      else {
        return this->set == other.set;
      }
    }
  }
};
В итоге можно делать вот так:
C++
1
2
3
4
5
6
SetElement element1('x'); // элемент-атом
SetElement element2(someSet); // элемент-множество
if (element1.type == SetElement::ATOM) { // можно сделать методы isAtom() и isSet()
  std::cout << element1.atom;
}
element1 = element2; // element1 теперь тоже элемент-множество
К сожалению, придётся руками смотреть на тайп-токен, чтобы понять, какого типа этот элемент, и как его доставать: через .atom или через .set. В принципе, можно добавить сверху методы asAtom() и asSet(), которые будут ругаться, если типы не совпадают, и спрятать все эти поля внутрь, но это уж как хотите.
0
DU
1483 / 1059 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.09.2012, 21:21 #9
хотел бы уточнить у знающих:
union разве может не POD типы содержать? множество какое-то например.
старый стандарт?
новый стандарт?
0
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
21.09.2012, 21:45 #10
Цитата Сообщение от DU Посмотреть сообщение
хотел бы уточнить у знающих:
union разве может не POD типы содержать? множество какое-то например.
старый стандарт?
новый стандарт?
В старом может, но с дикими ограничениями: никаких своих конструкторов и деструкторов, никаких виртуальных функций и не трогать стандартный оператор copy-assign (Type::operator=(const Type&)). Так что тот мой пример выше наверняка не сработает :) По крайней мере, если хранить множество не как указатель.

В новом ограничение снято, но при условии, что все эти функции реализуются руками для юниона, если они нужны. (Ну и список, естессно, расширился move-конструктором/присваиванием.)
1
ValeryS
Модератор
6631 / 5038 / 466
Регистрация: 14.02.2011
Сообщений: 16,849
21.09.2012, 21:54 #11
Infinity3000,
посмотрел я на твою ссылку и пригорюнился
одна эта фраза
Как вы узнаете, объединения очень похожи на структуры,


Elfenlide,
попытаюсь объяснить своими словами
Объединения используют когда одни и те же данные нужно выразить разным способом
например(куски реальной программы для работы с контроллера с USB)
хост посылает контроллеру данные упакованные вот в такую структуру
C++
1
2
3
4
5
6
7
typedef struct{ 
  byte bmRequestType;//0
  byte bRequest;     //1
  word wValue;       //2-3
  word wIndex;       //4-5
  word wLength;      //6-7
} SETUP_PACKET;
иногда нужно значение первых 2 элементов вместе
их удобно объединить
C++
1
word         wRequest;
но хост посылает последовательно 8 байт и как их вписать в слово word wValue;?
и тут приходит на помощь объединение

C++
1
2
3
4
5
6
typedef union
{
  SETUP_PACKET setup;
  byte         b[8];
  word         wRequest;
} UsbSetupPacket;
т.е одни и те же данные можно представить
массив из 8 байтов
структуру SETUP_PACKET
и слово wRequest(используются два первых байта)

и работаем
C++
1
UsbSetupPacket SetupPacket;
при получении данных нам удобней работать с массивом
C++
1
2
  for (i=0; i<8; i++)
   SetupPacket.b[i]= Usb_read_byte();
при анализе пакета с wRequest;
C++
1
2
3
  switch (SetupPacket.wRequest)  
  {
    case GET_STATUS_DEVICE:
а для обработки со структурой

C++
1
2
3
 if (SetupPacket.setup.wValue ==0x00  )     //  FEATURE_ENDPOINT_HALT
      {
       wIndex = (SetupPacket.setup.wIndex & 0x7F );
так же можешь разложить int на массив char
C++
1
2
3
4
5
union
  {
   ArrChar char[4];
   Value int; 
  }
в зависимости от элемента будешь работать или с массивом байт или с числом
2
Elfenlide
23 / 23 / 1
Регистрация: 15.04.2012
Сообщений: 183
22.09.2012, 00:01  [ТС] #12
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
В старом может, но с дикими ограничениями: никаких своих конструкторов и деструкторов, никаких виртуальных функций и не трогать стандартный оператор copy-assign (Type::operator=(const Type&)). Так что тот мой пример выше наверняка не сработает :) По крайней мере, если хранить множество не как указатель.

В новом ограничение снято, но при условии, что все эти функции реализуются руками для юниона, если они нужны. (Ну и список, естессно, расширился move-конструктором/присваиванием.)
Спасибо большое, теперь уже более менее понятно, думаю сам уже на практике доработаю.
Ещё один вопрос:
Откуда такие знания?)Дело в том что я смотрел несколько книг разных по С++, и везде один пример на ввод и вывод элементов разного типа, и просто синтаксис объявления, а толкового ничего нету.Какие книги вы посоветуете может из тех в которых можно полноценно черпать информацию?
0
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
22.09.2012, 00:06 #13
Естессно, я не помню наизусть тонкости. Интересуют тонкости — открываем стандарт (новый) и читаем. Вот оттуда я и вычитал про конкретные ограничения (так-то только смутно помню, что туда засунуть можно только классы, которые не особо круче сишных структур).
0
Elfenlide
23 / 23 / 1
Регистрация: 15.04.2012
Сообщений: 183
22.09.2012, 00:11  [ТС] #14
Цитата Сообщение от ValeryS Посмотреть сообщение
Infinity3000,
посмотрел я на твою ссылку и пригорюнился
одна эта фраза
Спасибо большое
0
ValeryS
Модератор
6631 / 5038 / 466
Регистрация: 14.02.2011
Сообщений: 16,849
22.09.2012, 00:26 #15
Цитата Сообщение от Elfenlide Посмотреть сообщение
Откуда такие знания?)Дело в том что я смотрел несколько книг разных по С++, и везде один пример на ввод и вывод элементов разного типа,
если вопрос к ~OhMyGodSoLong~, то он уже ответил
а если ко мне то отвечу словами Гете
"Теория без практики мертва, а вечно зелено лишь древо жизни"
изучай побольше исходников , задавай вопросы, ну и книги тоже читай но отбрасывай ненужное

кстати я тоже долго не пользовался объединениями поскольку объяснения были как на той ссылке
но увидев пару раз их применения

не это
Цитата Сообщение от Elfenlide Посмотреть сообщение
union distance
{
int miles;
long meters;
} walk;
а нормальное например как я привел, понял их силу

а с учебниками особенно с нашими будь осторожней
недавно тема проскакивала
привели методичку 2012 для работы с BC 3.1( лет десять наверно тупо перепечатывали)
смотри переводную литературу, а если знания позволяют читай в оригинале
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.09.2012, 00:26
Привет! Вот еще темы с ответами:

union с методами - C++
Такой вопрос - когда в union-е поля, то все ясно - оно занимает место, равное наибольшему размеру типов его полей, а когда в нем есть ещё и...

Управляемый value union - C++
Добрый вечер. Пытаюсь создать такую структуру: using namespace std; union actiondata{ char *filename; double delta; }; ...

Union, struct - C++
Здравствуйте! Помогите, пожалуйста, решить проблему. Есть строки: 1 2 3 4 1 2 3 ... ... * - заканчивается звездочкой

обьединения union - C++
вот собственно код struct х{ union { struct a { string name_c; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
22.09.2012, 00:26
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru