- p. 1/14
Zaawansowane programowanie w C++ (PCP)
Wykład 3 - polimorfizm.
dr in˙z. Robert Nowak
» Powtórzenie
Polimorfizm
- p. 2/14
Powtórzenie
Powtórzenie:
klasy autonomiczne: konstruktor, konstruktor kopiuj ˛acy, operator przypisania, destruktor
tworzenie nowych typów: dziedziczenie i agregacja
dziedziczenie: nadpisywanie metod, problem przycinania, zasłanianie
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 3/14
Polimorfizm
Zalety podej´scia obiektowego:
klasy autonomiczne
enkapsulacja (ochrona składowych)
konstrukcja i destrukcja
polimorfizm - brak odpowiednika w podej´sciu strukturalnym.
umo˙zliwia definiowanie ogólnych cech pokrewnych typów;
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 4/14
Problem typu dla obiektów
Problem wołania wła´sciwych metod dla obiektu, gdy u˙zywa si ˛e wska´znika do obiektu 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
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 5/14
Rozwi ˛ azanie: pole typu
class Osoba { public:
enum Typ { OSOBA, PRACOWNIK, KLIENT };
const Typ typ_;//Pole pami˛eta typ obiektu Osoba() : typ_(OSOBA) {}
};
class Pracownik : public Osoba { public:
Pracownik() : typ_(PRACOWNIK) {}
};
void drukuj(const Osoba& o) { switch(o.typ)
...
}
Bardzo złe rozwi ˛azanie!
kompilator nie potrafi sprawdzi´c poprawno´sci
kod staje si ˛e nieczytelny i trudno modyfikowalny
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 6/14
Funkcje wirtualne
Inne rozwi ˛azanie problemu pola typu, wspierane przez kompilator.
class Osoba {
virtual void drukuj(ostream& os) const { };
};
metoda jest wirtualna je˙zeli w klasie bazowej jest poprzedzona słowem virtual
metody s ˛a nadpisywane (zast ˛epowane) w klasie pochodnej
maj ˛a identyczn ˛a sygnatur ˛e
w klasie pochodnej metoda mo˙ze by´c (ale nie musi) poprzedzona słowem virtual
class Pracownik : public Osoba {
virtual void drukuj(ostream& os) const { os << ¨pracownik¨;
};
};
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 7/14
Polimorfizm
kompilator wybiera najbardziej wła´sciw ˛a metod ˛e (w´sród nadpisywanych)
wyj ˛atek: jawne wskazanie funkcji, np.
Prostokat::drukuj()
nadpisywanie bardziej restrykcyjne ni˙z przedefiniowywanie Zastosowania:
umo˙zliwia definiowanie ogólnych cech pokrewnych typów;
mo˙zna pisa´c ogólne funkcje działaj ˛ace dla wszystkich pochodnych pewnej klasy bazowej;
elastyczny system typów: mo˙zna dodawa´c nowe typy bez modyfikacji ju˙z istniej ˛acego kodu;
Znajdowanie cech wspólnych dla typów nie jest prostym zadaniem.
Mechanizm funkcji wirtualnych w innych j ˛ezykach programowania i w C++.
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 8/14
Pó´zne wi ˛ azanie
class A { public:
virtual void f(){};
virtual void g(){};
private:
//SkladoweA };
class B : public A { public:
virtual void f(){};
virtual void g(){};
private:
//SkladoweB
};
A a;
B b;
A* pa = b;
pa->f();
vtbl
vtbl
składoweA
składoweB składoweA
&A::f
&B::f
&A::g
&B::g obiektA
obiektB
Pó´zne wi ˛azanie (narzuty)
pami ˛eciowe: jeden wska´znik w obiekcie (vtbl)
czasowe: jeden skok wi ˛ecej
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 9/14
Destruktor
Je˙zeli klasa jest klas ˛a bazow ˛a, to powinna mie ´c wirtualny destruktor!
class Bazowa { };
class Pochodna : public Bazowa { };
Bazowa* ptr = new Pochodna();
delete ptr;//Bł ˛ad! Wywoła si˛e destruktor dla bazowa.
class Bazowa2 {
virtual ˜Bazowa2(){}
};
class Pochodna2 : public Bazowa2 { };
Bazowa2* ptr2 = new Pochodna2();
delete ptr2;//Wywoła si˛e destruktor dla Pochodna2
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 10/14
Polimorfizm
funkcje wirtualne, pó´zne wi ˛azanie
kompilator wybiera najbardziej wła´sciw ˛a metod ˛e (w´sród nadpisywanych)
wyj ˛atek: jawne wskazanie funkcji, np.
Prostokat::drukuj() Zastosowania:
umo˙zliwia definiowanie ogólnych cech pokrewnych typów;
mo˙zna pisa´c ogólne funkcje działaj ˛ace dla wszystkich pochodnych pewnej klasy bazowej;
elastyczny system typów: mo˙zna dodawa´c nowe typy bez modyfikacji ju˙z istniej ˛acego kodu;
Znajdowanie cech wspólnych dla typów nie jest prostym zadaniem.
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 11/14
Klasy abstrakcyjne
Klasy abstrakcyjne:
klasy, które maj ˛a sens jedynie jako interfejs (klasa bazowa)
nie mo˙zna dostarczy´c sensownej implementacji metod wirtualnych
nie powinny by´c tworzone obiekty takiej klasy
cz˛esto reprezentuje abstrakcyjne poj ˛ecie
Funkcje czysto wirtualne:
class Figura {
virtual void rysuj() = 0;
};
Je˙zeli klasa zawiera funcje czysto wirtualne to jest klas ˛a abstrakcyjn ˛a.
kompilator nie dopuszcza do tworzenia obiektów takich klas
wykrywany bł ˛ad obcinania ju˙z na etapie kompilacji!
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 12/14
Hierarchie klas
class Figura { public:
virtual void rysuj() = 0;
virtual bool czyWypukla() = 0;
};
class Wielokat : public Figura { public:
virtual
bool czyWypukla(){ return true;}
protected:
std::vector<Point> wierz_;
};
class Prostokat : public Wielokat { public:
virtual void rysuj();//Implementacja };
Koło Wielokąt Złożona Figura
Trójkąt Prostokąt
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 13/14
Interfejsy
Klasa abstrakcyjna:
nie musi dostarcza´c konstruktorów
stanowi interfejs dla swoich klas pochodnych, tzn. okre´slamy metody jakie te klasy musz ˛a implementowa´c
bardzo wygodne rozdzielenie interfejsu od implementacji Czysty interfejs:
klasa abstrakcyjna składaj ˛aca si ˛e głównie z funkcji czysto wirtualnych
nie przechowuje stanu
tylko okre´sla interfejs
» Powtórzenie
Polimorfizm
» Polimorfizm
» Problem typu dla obiektów
» Rozwi ˛azanie: pole typu
» Funkcje wirtualne
» Polimorfizm
» Pó´zne wi ˛azanie
» Destruktor
» Polimorfizm
» Klasy abstrakcyjne
» Hierarchie klas
» Interfejsy
» Wła´sciwo´sci klasy bazowej
- p. 14/14
Wła ´sciwo ´sci klasy bazowej
Klasa warto´s´c (klasa autonomiczna):
brak metod wirtualnych
konstruktor, konstruktor kopiuj ˛acy, operator przypisania, destruktor
najcz˛e´sciej obiekt automatyczny lub składowa klasy
przekazywany przez warto´s´c lub stał ˛a referencj ˛e Klasa bazowa dla hierarchii klas:
u˙zywa metod wirtualnych, powinna mie´c wirtualny destruktor
najlepiej gdy abstrakcyjna albo prywatny konstruktor kopiuj ˛acy i operator przypisania (zapobiega wycinaniu)
najcz˛e´sciej obiekt na stercie
przekazywana przez wska´znik lub referencj ˛e