( rednio)zaawansowane programowanie w C++ Wykªad 2 - staªo±, wzorce projektowe Robert Nowak 2017L ( rednio)zaawansowane programowanie w C++ 1/28
Plan wykªadu podstawowe poj cia w C++ (powtórzenie) staªo± zyczna i logiczna (powtórzenie) agregacja i dziedziczenie (powtórzenie) wzorce projektowe prototyp kompozyt proxy fasada ( rednio)zaawansowane programowanie w C++ 2/28
Staªo± Hierarchie klas Deklaracja i denicja Deklaracja - sygnalizacja»e pewna nazwa odnosi si do czego± extern int x; //deklaracja obiektu long silnia(long n); //deklaracja funkcji class Logger; //deklaracja klasy template<typename T> class Node; //deklaracja szablonu Denicja - podanie szczegóªów; int x = 4; //definicja i inicjacja zmiennej x long silnia(long n) { //definicja funkcji if(n < 2) return 1; return n * silnia(n-1); Inicjacja - nadanie pocz tkowej warto±ci Denicja obiektu: wtedy gdy mo»na zainicjowa ( rednio)zaawansowane programowanie w C++ 3/28
Staªo± Hierarchie klas Czas»ycia obiektów l-warto± : odnosi si do czego± co istnieje w pami ci. Obiekt: ma typ oraz unikalny identykator. automatyczne tworzone w chwili napotkania denicji s niszczone w momencie wyj±cia z zasi gu (np. z bloku) statyczne (globalne i zadeklarowane jako static) tworzone tylko raz s niszczone po zako«czeniu programu dynamiczne (tworzone na stercie) tymczasowe operatory new i delete (uwaga! oddzielna wersja dla tablic), programista steruje czasem»ycia obiektów (tworzy je i usuwa), Nie u»ywamy funkcji z <stdlib.h>, czyli malloc, free itp. ( rednio)zaawansowane programowanie w C++ 4/28
Staªo± Hierarchie klas Preprocesor (unika wykorzystania preprocesora) Preprocesora nale»y u»ywa jedynie do: doª czania plików nagªówkowych (#include) zabezp. nagªówków przed wielokrotnym doª czaniem kompilacji warunkowej Makrodenicje (#dene) - zamiast prostych stosowa staªe - zamiast zªo»onych szablony funkcji const int MAX = 20; //staªa globalna class Foo { static const int SIZE = 30; //staªa globalna, dost pna dla metod template<typename T> inline void max(const T& a, const T& b) { if(a > b) return a; else return b; } ( rednio)zaawansowane programowanie w C++ 5/28
Staªo± Hierarchie klas Staªo± (const) informuje programistów,»e dany obiekt nie b dzie zmieniany unika si magicznych liczb w kodzie (staªe maj nazwy) pozwala si kompilatorowi na optymalizacje int i = 2, j = 3; const int* p = &i;//lub 'int const* p', staªa warto± wskazywana p = &j; /* OK */ *p = 4; /* bª d */ int* const q = &i;//staªy wska¹nik q = &j; /* bª d */ *q = 4; /* OK */ const int* const r = &i; //staªy wska¹nik, staªa warto± wskazywana const int TAB[] = { 2, 3, 8, 5 //tablica staªych const int TAB_SIZE = sizeof(tab)/sizeof(tab[0]); std::vector<int> v(tab, TAB + TAB_SIZE); //inicjacja wektora std::vector<int>::const_iterator it2 = v.begin(); ++it2; /* OK */ *it2 = 8; /* bª d */ const std::vector<int>::iterator it = v.begin(); ++it; /* bª d */ *it = 5; /* OK */ ( rednio)zaawansowane programowanie w C++ 6/28
Staªo± Hierarchie klas Metody staªe uªatwia zrozumienie interfejsu klasy mo»na woªa dla obiektów, które s staªe class Foo { public: void f() const;//metoda staªa void f();//metoda o tej samej nazwie i parametrach void g(); const Foo f; f.g();//bª d f.f();//woªa metod 'void f() const' Aby zwi kszy wydajno± przekazywa argumenty przez staª referencj (const&) np. int funkcja(const Foo& f); Nie powiela kodu dla metod staªych modykator volatile ma podobn skªadni (ale znaczy co innego) ( rednio)zaawansowane programowanie w C++ 7/28
Staªo± Hierarchie klas Staªo± zyczna i logiczna class Foo { public: //Brak staªo±ci logicznej char* str() const { return str_; } //Brak staªo±ci fizycznej int getlength() { if(!validlength_) { length_ = strlen(str_); validlength_ = true; } return length_; } private: char* str_; bool validlength_; int length_; ( rednio)zaawansowane programowanie w C++ 8/28
Staªo± Hierarchie klas Staªo± zyczna i logiczna class Foo { public: //Brak staªo±ci logicznej char* str() const { return str_; } //Brak staªo±ci fizycznej int getlength() { if(!validlength_) { length_ = strlen(str_); validlength_ = true; } return length_; } private: char* str_; bool validlength_; int length_; class Foo { public: //Metoda ma staªo± logiczn const char* str() const { return str_; } //U»ycie modyfikatora mutable int getlength() const { if(!validlength_) { length_ = strlen(str_); validlength_ = true; } return length_; } private: char* str_; mutable bool validlength_; mutable int length_; ( rednio)zaawansowane programowanie w C++ 9/28
Staªo± Hierarchie klas Konwersja typów Nie u»ywa si rzutowania w stylu 'C'! nie u»ywa si void* konstruktory explicit Operatory rzutowania (unika ): static_cast - konwersj pomi dzy spokrewnionymi typami dynamic_cast - rzutowanie w dóª hierarchii klas const_cast - znosi kwalikator const reinterpret_cast - dowolna konwersja (tak jak w C) double d = 3.2; int i = static_cast<int>(d); //przykªad rzutowania ( rednio)zaawansowane programowanie w C++ 10/28
Staªo± Hierarchie klas Tworzenie nowych klas Wielokrotne wykorzystanie kodu: Wykorzystanie istniej cych klas bez naruszania ich implementacji. Mo»liwo± szybkiej zmiany struktury programu. Budowa klas na podstawie ju» istniej cych: agregacja, dziedziczenie. Agregacja: prostsza kontrola - nale»y j faworyzowa J zyk UML (Unied Modeling Language) - diagram klas. ( rednio)zaawansowane programowanie w C++ 11/28
Staªo± Hierarchie klas Agregacja - relacja skªada si z lub posiada Agregacja- gdy budowa z mniejszych kawaªków wi kszej caªo±ci. Nauczyciel + dajnazwisko() - nazwisko Przedmiot + dajnazwę() - nazwa class Przedmiot { /*... */ class Nauczyciel { private: std::vector<przedmiot*> przedm_; Kompozycja - agregacja, gdy obiekt skªadowy nie mo»e istnie bez obiektu gªównego Samochód + dajmarkę() - marka Silnik + dajpojemność() - pojemność class Silnik { /*... */ class Samochod { private: Silnik silnik_; ( rednio)zaawansowane programowanie w C++ 12/28
Staªo± Hierarchie klas Dziedziczenie - relacja mo»e by traktowany jako Dziedziczenie wprowadza powi zanie pomi dzy typami. Pracownik + dajnazwisko() - nazwisko Kierownik + dajdział() - dział //klasa bazowa class Pracownik { //... //klasas pochodna class Kierownik : public Pracownik { //... Bazowa Pochodna ( rednio)zaawansowane programowanie w C++ 13/28
Staªo± Hierarchie klas Wycinanie Dziaªanie konstruktora kopiuj cego lub operatora przypisania: class Pracownik {... class Kierownik : public Pracownik {... Kierownik k(...); Pracownik p = k; kopiuje tylko cz ± klasy, ¹ródªo niespodzianek i bª dów, rozwi zanie: przekazywanie wska¹ników lub referencji do obiektów. ( rednio)zaawansowane programowanie w C++ 14/28
Staªo± Hierarchie klas Typy klas Klasa warto± (klasa autonomiczna): brak metod wirtualnych konstruktor, konstruktor kopiuj cy, operator przypisania, destruktor najcz ±ciej obiekt automatyczny lub skªadowa klasy mo»e by przekazywana przez warto± Klasa bazowa dla hierarchii klas: u»ywa metod wirtualnych, powinna mie wirtualny destruktor najlepiej gdy abstrakcyjna albo prywatny konstruktor kopiuj cy i operator przypisania (zapobiega wycinaniu) najcz ±ciej obiekt na stercie przekazywana przez wska¹nik lub referencj ( rednio)zaawansowane programowanie w C++ 15/28
standardowe rozwi zania cz sto pojawiaj cych si problemów projektowych sprawdzone w praktyce najcz ±ciej dotycz programowania obiektowego znajomo± wzorców projektowych pozwala lepiej zrozumie obiektowe podej±cie do programowania Przykªad: Singleton ( rednio)zaawansowane programowanie w C++ 16/28
pªytka kopia (shell copy) Obj* obj = new Obj(); Obj* copy = obj; ( rednio)zaawansowane programowanie w C++ 17/28
gª boka kopia (deep copy) Obj* obj = new Obj(); Obj* copy = new Obj(*obj); ( rednio)zaawansowane programowanie w C++ 18/28
gª bokia i pªytka kopia class B { class D1 : public B { class D2 : public B { vector<b*> v; v.push_back(new D1); v.push_back(new D2); vector<b*> u = v; //Pªytka kopia vector<b*> uu; for(vector<b*>::const_iterator i = v.begin(); i!= v.end(); ++i) uu.push_back(new B(**i)); //WYCINANIE! for(const B* b : v) uu.push_back(new B(*b)); //p tla C++11, WYCINANIE! ( rednio)zaawansowane programowanie w C++ 19/28
Wzorzec prototypu odpowiedzialno± przeniesiona na obiekty pochodne wykorzystanie mechanizmu funkcji wirtualnej Client Base + clone() ConcreteA ConcreteB + clone() + clone() ( rednio)zaawansowane programowanie w C++ 20/28
prototyp (clone, wirtualny konstruktor) - przykªad class B { public: virtual B* clone() const = 0;//tworzy kopie danego obiektu private: B(const B&);//Zabroniony konstruktor kopiuj cy class D1 : public B { public: D1(const D1& r);//konstruktor kopiuj cy virtual B* clone() const { return new D1(*this); //Ju» wie, jaki typ kopiowa! } vector<b*> v1; vector<b*> v2; //tutaj b dzie gª boka kopia v1 for(vector<b*>::const_iterator i = v1.begin(); i!= v1.end(); ++i) v2.push_back( i->clone() ); for(const B* b : v1 ) //inny rodzaj p tli, C++11 v2.push_back( b->clone() ); ( rednio)zaawansowane programowanie w C++ 21/28
Wzorzec kompozytu reprezentacja drzewiastych struktur obiektów traktowanie w ten sam sposób obiektów prostych i zªo»onych ªatwo dodawa nowe klasy do hierarchii Klient Komponent funkcja() dodaj(komponent*) usun(komponent*) ProstyA funkcja() ProstyB funcja() Z o ony funkcja() dodaj(komponent*) usun(komponent*) ( rednio)zaawansowane programowanie w C++ 22/28
Kompozyt - przykªad class Fig { public: virtual void draw() = 0; virtual ~Fig(){} class Circle : public Fig { public: virtual void draw(); //rysuje okr g zlozona okrag zlozona trojkat trojkat trojkat class Composite : public Fig { public: virtual void draw() { //dla ka»dego dziecka wywoªuje 'draw' for(fig* f : children_) f->draw(); } private: std::vector<fig*> children_; ( rednio)zaawansowane programowanie w C++ 23/28
Wzorzec proxy Kontroluje dost p do obiektu (podobny do wska¹nika) obiekt w innej przestrzeni adresowej (np. na innym komputerze) (Remote Proxy) tworzy obiekt przy pierwszym u»yciu (Virtual Proxy) odkªada utworzenie kopii obiektu (Copy-On-Write Proxy) kontroluje prawa dost pu do obiektu (Protection Proxy) synchronizuje dost p do obiektu (Synchronization Proxy) niszczy obiekt na stercie (Smart Pointer) ( rednio)zaawansowane programowanie w C++ 24/28
Przykªad - tworzenie przy pierwszym u»yciu Client Interface operation() Proxy Real operation() operation() class Image { //Interfejs public: virtual void draw() = 0; class RealImage : public Image { public: RealImage(std::string& name) { /* wczytuje obrazek */ } class ProxyImage : public Image { //Przechowuje tylko nazw obrazka public: ProxyImage(std::string& name) : name_(name), realobj_(0l) {} virtual void draw(){getimage()->draw();}//woªa rzeczywisty obiekt private: std::string name_; Image* realobj_; Image* getimage() { if(!realobj_) realobj_ = new RealImage(name_); return realobj_; } ( rednio)zaawansowane programowanie w C++ 25/28
std::string (cz sto implementowany jako copy-on-write) //Uwaga: string cz sto implementowany jako proxy-on-write void f(string s) { s += 'a';//modyfikacja napisu } Inna optymalizacja (dla krótkich napisów STLPort) ( rednio)zaawansowane programowanie w C++ 26/28
Wzorzec fasady uproszczenie korzystania ze zªo»onego systemu zapewnienie wymienno±ci podsystemu Fasada metoda1() metoda2() z o ony podsystem ( rednio)zaawansowane programowanie w C++ 27/28
Dodatkowa lektura (http://staff.elka.pw.edu.pl/~rnowak2/rnbib.html): R. Nowak, Tworzenie kopii obiektów - wzorzec prototypu, Software Developer's Journal, 2010 R. Nowak, Staªo± - staªo± logiczna i staªo± zyczna, Software Developer's Journal, 2010 Dzi kuj ( rednio)zaawansowane programowanie w C++ 28/28