[C++] Kilka pytań dotyczących unii, klas i struktur

Witam!

Mam kilka pytań dotyczących unii:

1.

Funkcje składowe w unii mają sens tylko wtedy, kiedy pracują na jednym jej składniku :?: Bo i tak jak np. będziemy pracować na kilku to tylko ten ostatni jest brany pod uwagę. Przykład:

#include 


using namespace std;

//////////////////////////////////////////////////

union bank

{

    int licz;

    double wspol;

    bank(int liczba, double wspolczynnik)

    {

        licz = liczba;

        wspol = wspolczynnik; //zapisujemy coś do nowego - stary ginie

    }

};

//////////////////////////////////////////////////

int main()

{


    bank duzy(456, 78.5);


    cout << "wspol z unii - " << duzy.wspol; //78.5

    cout << "\nlicz z unii - " << duzy.licz; //0 !


}

Tak :?: Te “chwyty” w unii: 2. :arrow: inicjalizacja zbiorcza, czyli np.: (klasa to jakaś tam nazwa klasy ^.^)

klasa obiekt = { 67.8 };

jest też możliwa w strukturach i klasach, zgadza się :?: 3. :arrow: eee jakby to powiedzieć - definicja obiektów po klamrze zamykającej:

union

{

      //...

} obiekt, *wskaznik;

jest też możliwa w klasach i w strukturach :?: 4. Nie możliwe jest zrobienie klasy lub struktury anonimowej, ale powyższy chwyt jest wtedy dozwolony (mamy do dyspozycji tylko np. jeden obiekt klasy) :?: 5. Klasę lub strukturę też można zrobić statyczną jeżeli nie chce się, żeby była znana poza plikiem, tak jak jest w unii, prawda :?: 6. Trochę nie na temat ale jednak zadam to pytanie bo trochę wiąże się z tematem postu. Co prawda unia nie może być znana poza plikiem, ale może być (chyba) znana przestrzeń nazw. Jak mamy np. main.cpp :

namespace przestrzen

{

       int liczba;

}

//---------------------------

int main()

{

           //...

}

to jak w drugim pliku zasygnalizować istnienie zmiennych z przestrzeni nazw z 1-szego pliku (main.cpp) :?: Poprzez deklarację każdego z nich, tj. np.

extern przestrzen::liczba;

a potem zwykłe używanie (ale oczywiście nie zmienianie wartości ich):

cout << przestrzen::liczba;

:?:

_________________________________________________________________________________________

Z góry wielkie dzięki za odpowiedzi :slight_smile:

  1. [*:3smter4j]Nie.

    union ZapisDouble{ double Liczba; unsigned char Reprezentacja[sizeof(double)]; ZapisDouble(double Liczba=0):Liczba(Liczba) {} ZapisDouble(const char Dane) { memcpy(Reprezentacja,Dane,sizeof(double)); } void Wpisz(double Liczba) { ZapisDouble::Liczba=Liczba; } void Wpisz(char V,int pos) { Reprezentacja[pos]=V; } double Pobierz()const { return Liczba; } unsigned char Pobierz(int pos)const { return Reprezentacja[pos]; } }; [/code]Wpisujesz jako double a potem czytasz jako bajty, albo na odwrót.[:3smter4j]W takiej postaci tak dopoki niema konstruktorów, jak są to tylko podajać konstruktor:

    [code=php]struct Punkt{ double x,y; Punkt():x(0),y(0) {} Punkt(double x,double y):x(x),y(y) {} };Punkt P1=Punkt(),P2=Punkt(3,5),P3/tu domyślny zadziała/,P4(7,8),T1[]={Punkt(),Punkt(3,7)},T2[5]/5 razy domyślny/; [:3smter4j]Jak najbardziej: klasy, struktury, unii.[:3smter4j]Czemu nie można? Można:

    typedef struct { int x; } X,*WX,RX;X a,*b=a,c=a;WX wa=a,wb=b,wc=c; // uwaga wszystkie trzy są wskaźnikamiRX ra=wa,rb=wb,rc=wc; // uwaga wszystkie trzy są referencjami [/code][:3smter4j]Jak najbardziej, tylko poco? Wystarczy nie wpisywać do pliku nagłówkowego.[:3smter4j]Jedno z trzech:

    [code=php]using namespace przestrzen;coutliczba;

O dzięki wielkie [alex] :slight_smile:

Mam jeszcze tylko takie pytanie odnośnie unii (też to występuje w klasach). Czytałem, że daną składową klasy może być też obiekt innej klasy. To samo jest w unii, i tu mam problem. Bo załóżmy, np. że mamy klasę o nazwie bank , a w tej klasie jest dana składowa np. nazwa. Teraz w unii ( nie anonimowej - czyli w unii z nazwą :!: ) o nazwie np. jakas_unia definiuję sobie np. obiekt duzy typu bank. I teraz: jak przy użyciu unii, odwołać się do danej składowej nazwa :?:

Nie wiem jak to zrobić, a np. coś takiego jest błędem:

jakas_unia.duzy.nazwa;

Mam nadzieję, że wiecie co próbuję powiedzieć :lol:

Właśnie przez kropkę, coś w tym stulu:

struct A { int i; };

struct B { A obj_a; };

union C { B obj_b; };


C c_unia;

c_unia.obj_b.obj_a.i = 2;

Definicję przestrzeni umieść w pliku nagłówkowym i dołącz do drugiego pliku też oraz wywal te extern’y.

Przecież jest wtedy redefinicja tego :?

Jeszcze ostatnia rzecz - w unii nie może być składników o nieokreślonym rozmiarze (np. obiekty typu string) bo wtedy unia “nie wie” ile dokładnie miejsca trzeba na nią zarezerwować :?:

std::string ma określoną wielkość (sam obiekt), natomiast to że rezerwuje sobie dodatkowo pamięć to nie ma znaczenia. Analogicznie, możesz umieścić wskaźnik w unii, a to jaką wielkość ma coś na co wskazuje nie ma znaczenia, wskaźnik ma stałą wielkość. Tyle, że std::string w unii nie umieścisz, gdyż na typ, który może być składnikiem unii, nałożone jest parę warunków. Taki typ nie może mieć między innymi domyślnego konstruktora (poza definiowanym przez kompilator). W C++0x parę reguł związanych ze strukturami, uniami i typami POD ma zelżeć, ale na razie obowiązuje C++03.

Jak do dwóch plików składających się na jeden program dołączysz #include to będzie redefinicja obiektu cout? Tak jest trudne zajrzeć do pliku z include’ami i zobaczyć jak to jest zrobione? Owszem mogę wyjaśnić to i każdą inną rzecz o którą zapytasz, tylko że czy dobrze to na ciebie wpłynie? Stajesz się tak zależny od forum w swoim rozwoju że po “dorośnięciu” do średniego poziomu tego forum nie będziesz w stanie się rozwijać, bo nie będzie komu odpowiedzieć na twoje pytania. Może spróbuj tą drobną informacje wyszukać samodzielnie a zapewniam cię że poczujesz z tego o wiele większą satysfakcje niż z przeczytania odpowiedzi na forum.

:arrow: http://www.gamedev.net/community/forums … _id=471620

No dobra, chyba rzeczywiście będę musiał się bardziej postarać

A co do:

to to się ma nijak do mojego przykładu bo tam jest strażnik nagłówka, a poza tym nie wywala błędu ponieważ samo wstawienie pliku nagłówkowego klasy iostream, czyli sama definicja klasy nie powoduje zarezerwowania na nią pamięci miejsca, więc linkuje się to bez błędów. Tak przynajmniej czytałem na jakimś forum :slight_smile:

Zastanów się:

  1. [*:1chc0bsu]Strażnik zadziała tylko jeżeli podłączasz plik nagłówkowy do tego samego pliku po raz kolejny, czyli cały namespace jednak zostaje dołączony do każdego pliku i razem z każdym plikiem skompilowany.[*:1chc0bsu]Gdyby namespace nie dołączał się do drugiego pliku to skąd niby kompilator może wiedzieć jakie zmienne są w tym namespace a jakich niema.[*:1chc0bsu]O ile ostream rzeczywiście jest klasą, to cout jest obiektem tej klasy czyli jednak zmienną.