JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 12 1
KLASY ZAPRZYJAŹNIONE Jedna klasa (A) może zadeklarować przyjaźń z inną klasą (B). Oznacza to, że klasa B ma dostęp do wszystkich składników klasy A (ale nie odwrotnie!): class Klasa_B; //deklaracja zapowiadająca class Klasa_A { friend class Klasa_B; // deklaracja przyjaźni //... // reszta ciała klasy Klasa_A }; 2
KLASY ZAPRZYJAŹNIONE Przykład: 3
KLASY ZAPRZYJAŹNIONE Przykład: 4
KLASY ZAPRZYJAŹNIONE class Klasa_B; //deklaracja zapowiadająca class Klasa_A { friend class Klasa_B; // deklaracja przyjaźni //... // reszta ciała klasy Klasa_A }; o Jest możliwe, że klasa B również deklaruje przyjaźń z klasą A: class Klasa_B; class Klasa_A { friend class Klasa_B; //... // reszta ciała klasy Klasa_A }; class Klasa_B { friend class Klasa_A; // deklaracja przyjaźni //... // reszta ciała klasy Klasa_B }; 5
KLASY ZAPRZYJAŹNIONE Przykład: 6
KLASY ZAPRZYJAŹNIONE Przykład: 7
TABLICE OBIEKTÓW Można tworzyć tablice obiektów jakiejś klasy (podobnie jak w przypadku obiektów typów wbudowanych) Np. mając klasę: class Narzedzie { public: int numer; }; możemy stworzyć tablicę: Narzedzie klucz_plaski[10]; // tablica 10 obiektów klasy Narzedzie Jeśli chcemy się odnieść do danej składowej konkretnego obiektu: klucz_plaski[5].numer=13; cout<<klucz_plaski[5].numer; 8
TABLICE OBIEKTÓW Przykład (wersja 1): 9
TABLICE OBIEKTÓW Przykład (wersja 2): 10
TABLICE OBIEKTÓW Taka inicjalizacja tablicy obiektów jak na poprzednim slajdzie: Plyta album[3]={{"rhcp","californication"}, {"Iron Maiden","Powerslave"}, {"Tool", "10,000 Days"}}; jest możliwa dla tzw. agregatów. Agregat to klasa która: 1. Nie ma danych innych niż publiczne. 2. Nie ma konstruktorów. 3. Nie ma klas podstawowych. 4. Nie ma funkcji wirtualnych. o Dane podajemy w takiej kolejności, w jakiej są deklarowane w klasie. o Jeśli nie podamy wszystkich wartości reszta jest wypełniana zerami (lub ciągiem pustym). 11
TABLICE OBIEKTÓW Wracając do klasy Narzedzie: class Narzedzie { public: int numer; }; Stwórzmy tablicę obiektów: Narzedzie klucz_oczkowy[5]; // tablica 5 obiektów klasy Narzedzie Jeśli stworzymy wskaźnik do pokazywania na obiekty tej klasy: Narzedzie *wsk; i ustawimy go na konkretny element tablicy obiektów: wsk=&klucz_oczkowy[2]; to możemy się odnieść do danej składowej konkretnego obiektu: wsk->numer=23; tu: wpisujemy coś do składowej numer tego obiektu, na który pokazuje wskaźnik Oczywiście aby wskaźnik pokazywał na następny obiekt w tablicy wystarczy: wsk++; 12
TABLICE OBIEKTÓW Przykład: 13
TABLICE OBIEKTÓW A co jeśli klasa nie jest agregatem? Musimy wyposażyć klasę w konstruktor umożliwiający inicjalizację. Na liście inicjalizacyjnej umieszczamy wywołania konstruktorów dla poszczególnych obiektów tablicy. Przykład: następny slajd... 14
TABLICE OBIEKTÓW Przykład (już bez wskaźników): 15
OBIEKTY JAKO SKŁADNIKI KLASY o Danymi składowymi klasy mogą być obiekty innych klas. o Mówi się wówczas o złożeniu (agregacji, zawieraniu). o Zatem obiekt będący całością składa się z określonej liczby obiektów-składników: pl.wikipedia.org/wiki/rower 16
OBIEKTY JAKO SKŁADNIKI KLASY o np. jeśli mamy następującą klasę: class Wyswietlacz { //... // ciało klasy Wyswietlacz }; to (zapewne między innymi) obiekt klasy Wyswietlacz może być składnikiem klasy Smartfon: class Smartfon { //... Wyswietlacz moj_wysw; //... // reszta ciała klasy Smartfon }; o Złożenie stosuje się, gdy jakiś obiekt jest składnikiem innego obiektu. o Dziedziczenie stosuje się, gdy jakiś obiekt jest rodzajem innego obiektu (o tym przy dziedziczeniu...). 17
OBIEKTY JAKO SKŁADNIKI KLASY o Najpierw uruchamiane są konstruktory obiektów składowych, potem nadrzędnego (trzeba mieć z czego poskładać obiekt nadrzędny...) o Destruktory w odwrotnej kolejności. o Obiekt będący składnikiem innej klasy można inicjalizować jedynie za pomocą listy inicjalizacyjnej. Póżniej jest to już niemożliwe. o Oczywiście jeśli obiekt składowy nie ma konstruktora, to nie umieszcza się go na liście inicjalizacyjnej... o By pracować na oryginałach obiektów składowych a nie ich kopiach korzystamy z referencji (lub wskaźników) patrz: przykład 2. 18
OBIEKTY JAKO SKŁADNIKI KLASY Przykład 1: 19
OBIEKTY JAKO SKŁADNIKI KLASY o Konstruktor na poprzednim slajdzie miał postać (tu: definicja poza klasą): Lampka::Lampka (string naz, Zarowka zar): zarowa(zar) { nazwa=naz;}; o Konstruktor przyjmował argument w postaci obiektu klasy Zarowka.: Zarowka slaba(40,"zwykla"); // najpierw obiekt składowy Lampka lampa1("biurkowa",slaba); // potem obiekt nadrzędny o Gdybyśmy mieli dodatkowo konstruktor: Lampka::Lampka (string naz, int waty, string opis ): zarowa(waty,opis) { nazwa=naz;}; to moglibyśmy również tworzyć obiekt klasy Zarowka podając niezbędne dane do stworzenia obiektu składowego (tu: moc i opis żarówki): Lampka lampa2("stojaca",9,"diodowa"); 20
OBIEKTY JAKO SKŁADNIKI KLASY Przykład 2 (bardziej rozbudowany): 21
OBIEKTY JAKO SKŁADNIKI KLASY Przykład 2 (bardziej rozbudowany): 22