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