Polimorfizm
Transkrypt
Polimorfizm
Zaawansowane programowanie w C++ (PCP) Wykład 3 - polimorfizm. dr inż. Robert Nowak - p. 1/14 Powtórzenie » Powtórzenie Polimorfizm Powtórzenie: klasy autonomiczne: konstruktor, konstruktor kopiujacy, ˛ operator przypisania, destruktor tworzenie nowych typów: dziedziczenie i agregacja dziedziczenie: nadpisywanie metod, problem przycinania, zasłanianie - p. 2/14 Polimorfizm » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas Zalety podejścia obiektowego: klasy autonomiczne enkapsulacja (ochrona składowych) konstrukcja i destrukcja polimorfizm - brak odpowiednika w podejściu strukturalnym. umożliwia definiowanie ogólnych cech pokrewnych typów; » Interfejsy » Właściwości klasy bazowej - p. 3/14 Problem typu dla obiektów » Powtórzenie Polimorfizm » Polimorfizm Problem wołania właściwych metod dla obiektu, gdy używa sie˛ wskaźnika do obiektu klasy bazowej. » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej class Osoba { public: void drukuj(ostream& os) const { os << ¨osoba¨; } }; class Pracownik : public Osoba { public: void drukuj(ostream& os) const { os << ¨pracownik¨; } }; void drukujOsobe(const Osoba& f) { cout << f.drukuj(); } Osoba o; Pracownik p; drukujOsobe(o);//wołana metoda Osoba::drukuj drukujOsobe(p);//wołana metoda Osoba::drukuj - p. 4/14 Rozwiazanie: ˛ pole typu » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej class Osoba { public: enum Typ { OSOBA, PRACOWNIK, KLIENT }; eta typ obiektu const Typ typ_;//Pole pami˛ Osoba() : typ_(OSOBA) {} }; class Pracownik : public Osoba { public: Pracownik() : typ_(PRACOWNIK) {} }; void drukuj(const Osoba& o) { switch(o.typ) ... } Bardzo złe rozwiazanie! ˛ kompilator nie potrafi sprawdzić poprawności kod staje sie ˛ nieczytelny i trudno modyfikowalny - p. 5/14 Funkcje wirtualne » Powtórzenie Polimorfizm » Polimorfizm Inne rozwiazanie ˛ problemu pola typu, wspierane przez kompilator. » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm class Osoba { virtual void drukuj(ostream& os) const { }; }; » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej metoda jest wirtualna jeżeli w klasie bazowej jest poprzedzona słowem virtual metody sa˛ nadpisywane (zastepowane) ˛ w klasie pochodnej maja˛ identyczna˛ sygnature˛ w klasie pochodnej metoda może być (ale nie musi) poprzedzona słowem virtual class Pracownik : public Osoba { virtual void drukuj(ostream& os) const { os << ¨pracownik¨; }; }; - p. 6/14 Polimorfizm » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor kompilator wybiera najbardziej właściwa˛ metode˛ (wśród nadpisywanych) wyjatek: ˛ jawne wskazanie funkcji, np. Prostokat::drukuj() nadpisywanie bardziej restrykcyjne niż przedefiniowywanie » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej Zastosowania: umożliwia definiowanie ogólnych cech pokrewnych typów; można pisać ogólne funkcje działajace ˛ dla wszystkich pochodnych pewnej klasy bazowej; elastyczny system typów: można dodawać nowe typy bez modyfikacji już istniejacego ˛ kodu; Znajdowanie cech wspólnych dla typów nie jest prostym zadaniem. Mechanizm funkcji wirtualnych w innych jezykach ˛ programowania i w C++. - p. 7/14 Późne wiazanie ˛ » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej class A { public: virtual void virtual void private: //SkladoweA }; class B : public public: virtual void virtual void private: //SkladoweB }; A a; B b; A* pa = b; pa->f(); f(){}; g(){}; obiektA vtbl składoweA &A::f &A::g obiektB A { f(){}; g(){}; vtbl &B::f &B::g składoweA składoweB Późne wiazanie ˛ (narzuty) pamieciowe: ˛ jeden wskaźnik w obiekcie (vtbl) czasowe: jeden skok wiecej ˛ - p. 8/14 Destruktor » Powtórzenie Polimorfizm » Polimorfizm Jeżeli klasa jest klasa˛ bazowa, ˛ to powinna mieć wirtualny destruktor! » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ class Bazowa { }; class Pochodna : public Bazowa { }; » Destruktor » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej Bazowa* ptr = new Pochodna(); ˛ Wywoła si˛ e destruktor dla bazowa. delete ptr;//Bład! class Bazowa2 { virtual ˜Bazowa2(){} }; class Pochodna2 : public Bazowa2 { }; Bazowa2* ptr2 = new Pochodna2(); e destruktor dla Pochodna2 delete ptr2;//Wywoła si˛ - p. 9/14 Polimorfizm » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor funkcje wirtualne, późne wiazanie ˛ kompilator wybiera najbardziej właściwa˛ metode˛ (wśród nadpisywanych) wyjatek: ˛ jawne wskazanie funkcji, np. Prostokat::drukuj() » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej Zastosowania: umożliwia definiowanie ogólnych cech pokrewnych typów; można pisać ogólne funkcje działajace ˛ dla wszystkich pochodnych pewnej klasy bazowej; elastyczny system typów: można dodawać nowe typy bez modyfikacji już istniejacego ˛ kodu; Znajdowanie cech wspólnych dla typów nie jest prostym zadaniem. - p. 10/14 Klasy abstrakcyjne » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne Klasy abstrakcyjne: klasy, które maja˛ sens jedynie jako interfejs (klasa bazowa) nie można dostarczyć sensownej implementacji metod wirtualnych nie powinny być tworzone obiekty takiej klasy cz˛ esto reprezentuje abstrakcyjne pojecie ˛ » Hierarchie klas » Interfejsy » Właściwości klasy bazowej Funkcje czysto wirtualne: class Figura { virtual void rysuj() = 0; }; Jeżeli klasa zawiera funcje czysto wirtualne to jest klasa˛ abstrakcyjna. ˛ kompilator nie dopuszcza do tworzenia obiektów takich klas wykrywany bład ˛ obcinania już na etapie kompilacji! - p. 11/14 Hierarchie klas » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej class Figura { public: virtual void rysuj() = 0; virtual bool czyWypukla() = 0; }; Figura class Wielokat : public Figura { public: virtual Wielokąt Złożona bool czyWypukla(){ return true;} Koło protected: std::vector<Point> wierz_; }; Prostokąt Trójkąt class Prostokat : public Wielokat { public: virtual void rysuj();//Implementacja }; - p. 12/14 Interfejsy » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne » Hierarchie klas » Interfejsy » Właściwości klasy bazowej Klasa abstrakcyjna: nie musi dostarczać konstruktorów stanowi interfejs dla swoich klas pochodnych, tzn. określamy metody jakie te klasy musza˛ implementować bardzo wygodne rozdzielenie interfejsu od implementacji Czysty interfejs: klasa abstrakcyjna składajaca ˛ sie˛ głównie z funkcji czysto wirtualnych nie przechowuje stanu tylko określa interfejs - p. 13/14 Właściwości klasy bazowej » Powtórzenie Polimorfizm » Polimorfizm » Problem typu dla obiektów » Rozwiazanie: ˛ pole typu » Funkcje wirtualne » Polimorfizm » Późne wiazanie ˛ » Destruktor » Polimorfizm » Klasy abstrakcyjne Klasa wartość (klasa autonomiczna): brak metod wirtualnych konstruktor, konstruktor kopiujacy, ˛ operator przypisania, destruktor najcz˛ eściej obiekt automatyczny lub składowa klasy przekazywany przez wartość lub stała˛ referencje ˛ » Hierarchie klas » Interfejsy » Właściwości klasy bazowej Klasa bazowa dla hierarchii klas: używa metod wirtualnych, powinna mieć wirtualny destruktor najlepiej gdy abstrakcyjna albo prywatny konstruktor kopiujacy ˛ i operator przypisania (zapobiega wycinaniu) najcz˛ eściej obiekt na stercie przekazywana przez wskaźnik lub referencje ˛ - p. 14/14