Co to jest Unia?
Unia jest to tak jakby struktura zawierająca jedno miejsce w pamięci przeznaczone dla paru obiektów różnego typu. Wielkość unii zawsze jest równa miejscu zajmowanemu przez największy obiekt znajdujący się w unii. Tzn. deklarując unię zawierającą 3 zmienne int przydzielamy jej miejsce o wielkości jednej zmiennej int. Oczywiście nie możemy używać wszystkich zmiennych naraz, ponieważ mając do czynienia z unią zawierającą zmienne char i int będą po prostu w nich śmieci gdy korzystamy z innej zmiennej będącej w unii. Powtarzam, jeżeli nasza unia zawiera np. obiekt typu int i double i gdy aktualnie korzystamy z double(8B) to po odczytaniu wartości int(4B) bez uprzedniego zapisu do niej pokażą nam się zwykłe śmieci. Podkreślam, naraz używamy
tylko jednego obiektu. Obrazek pierwszy ilustruje pamięć używaną przez unię.
Przykładowy program uzywający unii
Kod:
#include <iostream>
using namespace std;
union unia
{
float u_zm1;
short int u_zm2;
};
int main()
{
unia pierw_unia;
pierw_unia.u_zm2 = 456;
pierw_unia.u_zm1 = 123.45;
cout << "Zmienna aktualna w unii: " << pierw_unia.u_zm1 << " - u_zm1\n";
cout << "Zmienna nie aktualna w unii: " << pierw_unia.u_zm2 << " - u_zm2\n";
pierw_unia.u_zm1 = 123.45;
pierw_unia.u_zm2 = 456;
cout << "Zmienna aktualna w unii: " << pierw_unia.u_zm2 << " - u_zm2\n";
cout << "Zmienna nie aktualna w unii: " << pierw_unia.u_zm1 << " - u_zm1\n";
}
Tłumaczenie:
union unia
{
float u_zm1;
short int u_zm2;
};
Tak definiujemy unię. Jak widzisz budową podobna jest ona do struktury z tym, że poprawny dostęp mamy tylko do jednej zmiennej w danej chwili. Oczywiście unia zajmuje też mniej miejsca. W unii również możemy używać słów private, public. Jednak nie można użyć w niej słowa protected, a to dlatego że unia
nie może mieć dziedzica.
Inicjalizacja unii
Podobnie jak w strukturze/klasie możesz sobie napisać konstruktor jednak nie będę tu tego omawiał, a w zamian za to opiszę tu użycie tzw. inicjalizacji zbiorczej.
Przykładowo to jest nasza unia:
union nasza_unia
{
char znak;
float liczba;
};
A oto przykład jak inicjalizować unię.
nasza_unia unia_01 = { ‘ b ’ };
Zwróć uwagę że takie zapisy są błędne:
nasza_unia unia_01 = { ‘ b ’, 20.34345 };
Zapis jest niepoprawny, gdyż pomimo że jest to inicjalizacja zbiorowa, to przecież unia ma jedno miejsce w pamięci dla paru obiektów i naraz może być używany tylko jeden.
nasza_unia unia_01 = { 20.34345 };
Ten zapis jest niepoprawny. Dlatego iż tym sposobem możemy inicjalizować tylko pierwszy obiekt zapisany w unii, czyli w naszym przypadku
tylko zmienną znak o typie char. Zwróć uwagę też na to iż posługujemy się nawiasami
klamrowymi, nie zwykłymi.
Unia anonimowa
Unia anonimowa jest to taki typ unii gdzie nie wpisujemy jej nazwy. W takim razie nie posługujemy się kropką/strzałką gdy odnosimy się do unii. Przykładowa anonimowa unia:
union
{
char znak;
float liczba;
};
I do takiej unii w programie odwołujemy się tak:
znak = ‘ a ’;
std::cout << znak;
Należy też pamiętać że nie możemy równocześnie zdefiniować drugiej zmiennej o takiej samej nazwie w tym samym obszarze kodu, a więc taki program jest błędny:
#include <iostream>
char znak;
union
{
char znak;
float liczba;
};
int main()
{
znak = ‘ a ’;
std::cout << znak;
}
Na koniec dodam że taki kod:
union
{
char znak;
float liczba;
} un_001;
oznacza to samo co:
union nasza_unia
{
char znak;
float liczba;
};
nasza_unia un_001;
Więc pierwszy przykład (oczywiście drugi też) kodu nie jest unią anonimową, pomimo iż nie zawiera nazwy.
Gdy do unii musimy odnosić się operatorem ‘.’ bądź ‘->’ to wiedz że nie jest ona anonimową.