Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałWeronika Andrzejewska Został zmieniony 9 lat temu
1
Dziedziczenie Wykład 7 Dziedziczenie sekwencyjne
Dziedziczenie wielobazowe (wielodziedziczenie) PO7-1 / 29
2
Dziedziczenie sekwencyjne
diagram dziedziczenia, przykład sekwencji klas, przykłady konwersji definiowanych, konflikt nazw. PO7-2 / 29
3
Przykład dziedziczenia
class Osoba{ protected:CString Imie,Nazwisko; CData data_urodzenia; /* pozostałe deklaracje */ }; class Pracownik:public Osoba{ protected:CStawka Wynagrodzenie; CData data_zatrudnienia; class Urzędnik:public Pracownik{ protected:CString NrPokoju,dział; class Kierownik:public Urzędnik{ protected:CStawka dodatek; Osoba Pracownik Urzędnik Kierownik PO7-3 / 29
4
Diagram dziedziczenia
Klasa A jest bazową dla klasy B. Klasa B jest bazową dla klasy C. itd. Każda z klas: B, C, D, E ma tylko jedną klasę bazową. Klasa A Klasa B class A{ /* deklaracje */ }; class B:public A{ class C:public B{ class D:public C{ class E:public D{ Klasa C Klasa D Klasa E PO7-4 / 29
5
Organizacja obiektów Obiekt klasy A Pola klasy A Obiekt klasy bazowej jest pierwszym polem obiektu klasy pochodnej. Obiekt klasy B Pola klasy B Podobiekt A Obiekt klasy C Pola klasy C Podobiekt klasy B Pola klasy C Pola klasy B Podobiekt A Obiekt klasy D Pola klasy D Podobiekt klasy C Pola klasy D Pola klasy C Pola klasy B Podobiekt A Obiekt klasy E Pola klasy E Podobiekt klasy D Pola klasy E Pola klasy D Pola klasy C Pola klasy B Podobiekt A PO7-5 / 29
6
Konstruktory Konstruktory klas: B, C, D, E muszą wywoływać, w liście
inicjacyjnej, konstruktory swoich klas bazowych, aby zainicjować podobiekty bazowe. // Konstruktor klasy A A::A(/*parametry dla A*/):// inicjatory pól klasy A {/*instrukcje funkcji konstruktora*/} // Konstruktor klasy B B::B(/*parametry dla B*/):A(/*argumenty dla A*/), // inicjatory pól klasy B {/*instrukcje funkcji konstruktora*/} // Konstruktor klasy C C::C(/*parametry dla C*/):B(/*argumenty dla B*/), // inicjatory pól klasy C {/*instrukcje funkcji konstruktora*/} PO7-6 / 29
7
Konstruktory c.d. // Konstruktor klasy D
D::D(/*parametry dla D*/):C(/*argumenty dla C*/), // inicjatory pól klasy D {/*instrukcje funkcji konstruktora*/} // Konstruktor klasy E E::E(/*parametry dla E*/):D(/*argumenty dla D*/), // inicjatory pól klasy E {/*instrukcje funkcji konstruktora*/} PO7-7 / 29
8
Destruktory Destruktory klas: A, B, C, D, E muszą tworzyć ciąg funkcji
polimorficznych. W tym celu w klasie A należy funkcję destruktora ~A( ) zadeklarować ze słowem virtual. // Definicja klasy A class A{ /*parametry dla A*/ // . . . public: virtual ~A( ); }; A *p=new E; // . . . delete p; W sytuacji posłużenia się wskaźnikiem na klasę bazową do usunięcia obiektu klasy pochodnej gwarantuje to automatyczne wywołanie destruktora klasy pochodnej do obiektu oraz destruktorów klas bazowych do każdego podobiektu. PO7-8 / 29
9
Destruktor wirtualny A *p=new E; // . . . delete p;
Zmienna p jest wskaźnikiem na klasę A. Zatem instrukcja delete p; aktywowałaby tylko destruktor z klasy A. Destruktor polimorficzny (wirtualny) wywołuje swoją postać nie z klasy wskaźnika, ale z klasy wskazywanego obiektu – tutaj z klasy E. Aby usunąć obiekt klasy E, trzeba najpierw usunąć jego podobiekt z klasy D, do którego też będzie wywołany destruktor z klasy D. Aby usunąć podobiekt klasy D, trzeba najpierw usunąć jego podobiekt z klasy C, do którego też będzie wywołany destruktor z klasy C. Itd. PO7-9 / 29
10
Usuwanie obiektów Obiekt klasy E
Pola klasy E Podobiekt klasy D Aktywowanie destruktora ~E( ) do obiektu klasy E Podbiekt klasy D Pola klasy D Podobiekt klasy C Aktywowanie destruktora ~D( ) do podobiektu klasy D Podbiekt klasy C Pola klasy C Podobiekt klasy B Aktywowanie destruktora ~C( ) do podobiektu klasy C Pola klasy B Podobiekt A Podbiekt klasy B Aktywowanie destruktora ~B( ) do podobiektu klasy B Pola klasy A Podbiekt klasy A Aktywowanie destruktora ~A( ) do podobiektu klasy A PO7-10 / 29
11
Punkt – Kolo - Walec Y Klasa Punkt y x, y, przesun(dx, dy) X x Y y
x+dx Y R R y Klasa Kolo (x, y), r X x x+dx Z h Klasa Walec (x, y, r), h x x+dx X y dy R dx R Y PO7-11 / 29
12
Przykład sekwencji klas
class Punkt { protected: double x, y; public: Punkt(double x=0, double y=0): x(x), y(y) { } void przesun(double dx, double dy) {x+=dx; y+=dy;} // . . . }; class Kolo: public Punkt { protected: double R; Kolo(double x=0, double y=0, double R=1):Punkt(x, y), R(R) { } class Walec: public Kolo { protected: double h; Walec(double x=0, double y=0, double R=1, double h=1): Kolo(x, y, R), h(h) { } PO7-12 / 29
13
Przykład Walec X(0,0,1,5); // x=0, y=0, R=1, h=5 Punkt P;
X.przesun(1,2); // aktywacja funkcji z klasy Punkt P=X; // standardowa konwersja - przypisanie x=1, y=2 do P Konwersje definiowane: Kolo::Kolo(Punkt &P): Punkt(P), R(1) { } Walec::Walec(Kolo &K): Kolo(K), h(1) { } Konwersje nie nakładają się automatycznie Punkt P(10,20); Kolo K=P; // konwersja domyślna (Kolo)P Walec X=(Kolo)P; // konwersja domyślna (Walec) PO7-13 / 29
14
Konflikt nazw Zdefiniowanie w klasie Walec funkcji
void przesun(double dx, double dy, double dh) {x+=dx; y+=dy; h+=dh;} przesłania w klasie Walec funkcję z klasy Punkt. Do przesłoniętych zmiennych i funkcji można się odwołać za pomocą operatora kwalifikacji klasy. Np. Walec X(0,0,1,5); Punkt P(10, 20); P.przesun(1,2); // funkcja z klasy Punkt X.przesun(1,2,3); // funkcja z klasy Walec X.przesun(1,2); // błąd X.Punkt::przesun(1,2); // funkcja z klasy Punkt PO7-14 / 29
15
Dziedziczenie wielobazowe
(wielodziedziczenie) diagram dziedziczenia, konstruktory klas pochodnych, przykład dziedziczenia, dziedziczenie wirtualne, konflikt nazw. PO7-15 / 29
16
Diagram dziedziczenia
Klasa A oraz klasa B są klasami bazowymi dla klasy C. Klasa C ma dwie klasy bazowe. Klasa C może mieć wiele klas bazowych. Klasa A Klasa B Klasa C class A{ /* deklaracje */ }; class B{ /* deklaracje */ }; class C:public A,public B{ /* deklaracje */ }; PO7-16 / 29
17
Organizacja obiektów Obiekty klas bazowych są polami obiektu klasy pochodnej. Konstruktory obiektów klas bazowych są wywoływane w kolejności takiej, w jakiej podano te klasy w definicji klasy pochodnej. Kolejność występowania konstruktorów w liście inicjacyjnej konstruktora klasy pochodnej nie ma znaczenia. Obiekt klasy A Pola klasy A Obiekt klasy B Pola klasy B Obiekt klasy C Pola klasy C Podobiekt A Podobiekt klasy B Konstruktor klasy C C::C( /*parametry*/ ): A( /*…*/ ), B( /*…*/ ) { /* treść konstruktora */ } PO7-17 / 29
18
Usuwanie obiektów Obiekt klasy C
Pola klasy C Podobiekt A Podobiekt klasy B Aktywowanie destruktora ~C( ) do obiektu klasy C Podobiekt klasy B Podobiekt A Aktywowanie destruktora ~B( ) do podobiektu klasy B Aktywowanie destruktora ~A( ) do podobiektu klasy A PO7-18 / 29
19
Przykład dziedziczenia
Silnik Odbiornik prądu Silnik elektryczny class Silnik{ /* deklaracje */ }; class OdbPradu{ /* deklaracje */ }; class SilnikEl:public Sinik,public OdbPradu{ /* deklaracje */ }; PO7-19 / 29
20
Dziedziczenie wielokrotne
Klasa Q Klasa A Klasa B Klasa D class Q{ /* definicje zmiennych i funkcji klasy Q */ } ; class A: public Q { /* klasy A */ } ; class B: public Q { /* klasy B */ } ; class D: public A, public B { /* klasy D */ } ; PO7-20 / 29
21
Budowa obiektu class Q{ /* ... */ } ;
class A: public Q { /* ... */ } ; class B: public Q { /* ... */ } ; class D: public A, public B { /* ... */ } ; D x; // definicja obiektu x z klasy D D A B A::Q B::Q Pola klasy Q Pola klasy A Pola klasy B Pola klasy D Przykład budowy obiektu klasy D Konstruktor klasy D D::D( /*parametry*/ ): A( /*…*/ ), B( /*…*/ ) { /* treść konstruktora */ } PO7-21 / 29
22
Dziedziczenie wirtualne
Klasa V v v Klasa A Klasa B Klasa D class V{ /* definicje zmiennych i funkcji klasy V */ } ; class A: virtual public V { /* klasy A */ } ; class B: virtual public V { /* klasy B */ } ; class D: public A, public B { /* klasy D */ } ; PO7-22 / 29
23
Budowa obiektu class V{ /* ... */ } ;
class A: virtual public V { /* ... */ } ; class B: virtual public V { /* ... */ } ; class D: public A, public B { /* ... */ } ; D x; // definicja obiektu x z klasy D D A B A , B V Pola klasy A Pola klasy B Pola klasy D Pola klasy V Przykład budowy obiektu klasy D Konstruktor klasy D D::D( /*parametry*/ ): A( /*…*/ ), B( /*…*/ ), V( /*…*/ ) { /* treść konstruktora */ } PO7-23 / 29
24
Dziedziczenie wirtualne
Klasa V Klasa Q v v Klasa A Klasa B Klasa D class V{ /* definicje zmiennych i funkcji klasy V */ } ; class Q{ /* definicje zmiennych i funkcji klasy Q */ } ; class A: virtual public V, public Q { /* klasy A */ } ; class B: virtual public V, public Q { /* klasy B */ } ; class D: public A, public B { /* klasy D */ } ; PO7-24 / 29
25
Budowa obiektu class V{ /* ... */ int k, n; } ;
class Q{ /* ... */ int p, s; } ; class A: virtual public V, public Q { /* ... */ } ; class B: virtual public V, public Q { /* ... */ } ; class D: public A, public B { /* ... */ int p, n; } ; D x; // definicja obiektu x z klasy D D A B A , B A::Q B::Q V Pola klasy Q Pola klasy A Pola klasy B Pola klasy D Pola klasy V Przykład budowy obiektu klasy D PO7-25 / 29
26
Dostęp do zmiennych p s n k class V{ /* ... */ int k, n; } ;
class Q{ /* ... */ int p, s; } ; class A: virtual public V, public Q { /* ... */ } ; class B: virtual public V, public Q { /* ... */ } ; class D: public A, public B { /* ... */ int p, n; } ; D x; // definicja obiektu x z klasy D Obiekt x A B A , B A::Q B::Q V p s Pola klasy A Pola klasy B n k x .A::s x .B::s x .p x .n x .V::n x .A::p x .B::p x .k PO7-26 / 29
27
Konflikt nazw funkcji class Silnik { /* ... */
public: double Sprawnosc( ); } ; class OdbPr { /* ... */ public: double Sprawnosc( ); } ; class SilnikEl: public Silnik, public OdbPr { /* ... */ } ; main( ) { SilnikEl x; // definicja obiektu x z klasy SilnikEl double S; S=x.Sprawnosc( ); // błąd!! – o którą funkcję chodzi? // Silnik::Sprawnosc( ) czy OdbPr::Sprawnosc( ) /* ... */ } PO7-27 / 29
28
Konstruktory Podobiekty klas bazowych muszą być inicjowane na liście
inicjacyjnej. V::V(/* ... */) { /* instrukcje konstruktora */ } Q::Q(/* ... */) { /* instrukcje konstruktora */ } A::A(/* ... */):V(/* ... */), Q(/* ... */) { /* instrukcje konstruktora */ } B::B(/* ... */):V(/* ... */), Q(/* ... */) { /* instrukcje konstruktora */ } PO7-28 / 29
29
Konstruktory V::V(/* ... */){ /* instrukcje konstruktora */ }
Q::Q(/* ... */){ /* instrukcje konstruktora */ } A::A(/* ... */):V(/* ... */), Q(/* ... */) { /* instrukcje */ } B::B(/* ... */):V(/* ... */), Q(/* ... */) { /* instrukcje */ } Podobiekty klas dziedziczonych wirtualnie muszą być inicjowane niezależnie na liście inicjacyjnej. D::D(/* ... */):A(/* ... */), B(/* ... */), V(/* ... */) { /* instrukcje konstruktora */ } // Powyżej dodatkowa inicjacja podobiektu klasy V // dziedziczonej wirtualnie w klasie D. PO7-29 / 29
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.