background image

1

Programowanie obiektowe

Wykład 4

Dziedziczenie

Konstruktory i destruktory

background image

2

Programowanie obiektowe

Dziedziczenie

Dziedziczenie to technika pozwalaj

ą

ca na definiowanie nowych klas przy 

wykorzystaniu klas wcze

ś

niej istniej

ą

cych

Wyra

Ŝ

a zwi

ą

zki hierarchiczne mi

ę

dzy klasami;

Specjalizuje lub generalizuje klasy;

Przykład:

ka

Ŝ

dy dorosły i ka

Ŝ

de dziecko jest osob

ą

 (generalizacja);

dorosły jest przypadkiem szczególnym osoby, podobnie jak dziecko
(specjalizacja);

osoba

dziecko

dorosły

klasa bazowa

klasy pochodne

background image

3

Programowanie obiektowe

Klasa pochodna:

dziedziczy wszystkie zmienne z sekcji „public” i „protected” klasy 
bazowej;

dziedziczy wszystkie funkcje z sekcji „public” i „protected” klasy 
bazowej;

do dost

ę

pnych składowych klasy bazowej mo

Ŝ

na si

ę

 odwoływa

ć

  

poprzez operator zakresu „::”;

W klasie pochodnej mo

Ŝ

na tak

Ŝ

e:

zdefiniowa

ć

 dodatkowe zmienne składowe;

zdefiniowa

ć

 dodatkowe funkcje składowe;

przedefiniowa

ć

 (zmieni

ć

) funkcje składowe odziedziczone

z klasy bazowej (polimorfizm);

Dziedziczenie

background image

4

Programowanie obiektowe

Posta

ć

 ogólna dziedziczenia:

class Klasa_pochodna: sekcja Klasa_bazowa_1 [, Klasa_bazowa_N]

{

// nowe składowe

// funkcje odziedziczone nadpisane (przedefiniowane)

};

tzw. dziedziczenie wielobazowe

Dziedziczenie

sekcja docelowa dla składowych 

dziedziczonych

background image

5

Programowanie obiektowe

Dziedziczenie

Je

Ŝ

eli w klasie bazowej i w klasie pochodnej s

ą

 składniki o tej samej 

nazwie, wówczas w zakresie klasy pochodnej składnik 
z tej klasy zasłania odziedziczony składnik z klasy bazowej

Je

ś

li składnik klasy bazowej jest zasłoni

ę

ty to odwołanie si

ę

 do niego 

jest mo

Ŝ

liwe z u

Ŝ

yciem operatora zakresu (::)

background image

6

Programowanie obiektowe

Przykład – klasa osoba

class osoba
{

int wiek;
char imi

ę

[20], nazwisko[30];

public:

void wczytaj(); 
void ustaw(int wiek, char *p_imi

ę

, char *p_nazwisko);

void wypisz();

}; 

background image

7

Programowanie obiektowe

Zało

Ŝ

enia rozszerzaj

ą

ce dla klasy „dorosly”:

numer dowodu:

char *nr_dowodu;

prywatny dla klasy „dorosly”;

metody wczytajwypiszustaw:

dost

ę

pne publicznie;

odziedziczone z klasy bazowej;

Przykład – klasa dorosly

background image

8

Programowanie obiektowe

Klasa „dorosly”

class dorosly: public osoba 
{

char * nr_dowodu;

public:

void wczytaj ();
void wypisz ();
void ustaw(int wiek, char *p_imie, char *p_nazwisko, 

char *nr_dow); 

};

klasa pochodna

klasa bazowa

sekcja docelowa dla składowych 

dziedziczonych

nowa składowa

metody odziedziczone ale przedefiniowane

Dziedziczenie

background image

9

Programowanie obiektowe

sekcja docelowa dla składowych dziedziczonych:

class Klasa_pochodna : 

public

Klasa_bazowa; 

// sekcja

// private

// sekcja

// protected

// sekcja

// public

Klasa_bazowa

// sekcja

// private

// sekcja

// protected

// sekcja

// public

Klasa_pochodna

Dziedziczenie

dziedziczone ale niedostępne w klasie 
pochodnej; dostępne poprzez 
dziedziczone funkcje nieprywatne

background image

10

Programowanie obiektowe

sekcja docelowa dla składowych dziedziczonych:

class Klasa_pochodna : 

protected

Klasa_bazowa;

// sekcja

// pivate

// sekcja

// protected

// sekcja

// public

Klasa_bazowa

// sekcja

// pivate

// sekcja

// protected

// sekcja

// public

Klasa_pochodna

Dziedziczenie

dziedziczone ale niedostępne w klasie 
pochodnej; dostępne poprzez 
dziedziczone funkcje nieprywatne

background image

11

Programowanie obiektowe

sekcja docelowa dla składowych dziedziczonych:

class Klasa_pochodna : 

private

Klasa_bazowa; 

// sekcja

// private

// sekcja

// protected

// sekcja

// public

Klasa_bazowa

// sekcja

// private

// sekcja

// protected

// sekcja

// public

Klasa_pochodna

Dziedziczenie

dziedziczone ale niedostępne w klasie 
pochodnej; dostępne poprzez 
dziedziczone funkcje nieprywatne

background image

12

Programowanie obiektowe

Z zakresu klasy pochodnej do prywatnych składników klasy 
bazowej mo

Ŝ

na si

ę

ga

ć

 tylko poprzez funkcje składowe klasy 

bazowej

Do składników protected public klasy bazowej mamy dost

ę

bezpo

ś

redni;

Dziedziczenie prywatne stosujemy wtedy, gdy chcemy aby nie było 
publicznego dost

ę

pu do odziedziczonych składników klasy 

bazowej;

Nie podlegaj

ą

 dziedziczeniu: 

konstruktory

destruktory

Dziedziczenie

trzeba je zdefiniować w klasie pochodnej

background image

13

Programowanie obiektowe

Dziedziczenie jest technik

ą

 definiowania nowych klas;

Dziedziczenie jest jedn

ą

 z najwspanialszych cech j

ę

zyków 

programowania obiektowego;

Umo

Ŝ

liwia:

oszcz

ę

dno

ść

 pracy,

tworzenie hierarchii klas (hierarchia wprowadza naturalne 
relacje mi

ę

dzy klasami),

tworzenie klas ogólnych (klas przeznaczonych do 
dziedziczenia np. ogólna klasa „kolejka”)

Dziedziczenie - podsumowanie

background image

14

Programowanie obiektowe

Przykład hierarchii klas

Dziedziczenie

samochód

osobowy

cięŜarowy

autobus

Fiat

VW

opel

„wywodzi się”

background image

15

Programowanie obiektowe

Zgodno

ść

 typów:

class KlasaA
{

}
class KlasaB: public KlasaA 
{

....

};

KlasaA  a;
KlasaB  b;

a = b; // ?

b = a; // ?

dozwolone, ale kopiuje si

ę

 tylko tyle, ile jest w KlasaA

niedozwolone 

Dziedziczenie - ograniczenia

zmienne obiektowe (obiekty)

background image

16

Programowanie obiektowe

Zgodno

ść

 typów:

KlasaA *ap;
KlasaB *bp;     

ap = bp;

// ?

bp = ap;

//  ? 

bp = (KlasaB*) ap;   

//  ?

bp dynamic_cast<KlasaB*>(ap);  // ?

Operator dynamic_cast zwraca 0 (dla wska

ź

ników) lub zgłasza 

bad_cast (dla referencji), gdy rzutowanie si

ę

 nie powiedzie;

poprawne (wyst

ą

pi polimorfizm

niedozwolone

dozwolone (styl j

ę

zyka C)

dozwolone (styl j

ę

zyka C++)

Dziedziczenie

wska

ź

niki na obiekty

background image

17

Programowanie obiektowe

Konstruktory

pierwsza (najcz

ęś

ciej publiczna) funkcja składowa obiektu, o nazwie 

takiej samej jak nazwa klasy;

słu

Ŝ

y do inicjowania obiektów danej klasy, tzn. do nadawania warto

ś

ci 

pocz

ą

tkowych składnikom definiowanego (wła

ś

nie) obiektu (w trakcie 

deklaracji obiektu przydziela mu si

ę

 miejsce w PAO);

metoda bezzwrotna (nie mo

Ŝ

na u

Ŝ

y

ć

nawet typu „void”!);

definiowany tak jak funkcja składowa: 

wewn

ą

trz deklaracji klasy – domy

ś

lnie „inline”;

poza deklaracj

ą

 klasy:

jak zwykła metoda;

jak metoda „inline”;

wywoływany automatycznie w momencie tworzenia (deklaracji) 
konkretnego obiektu;

konstruktor cz

ę

sto bywa przeci

ąŜ

any;

w przypadku braku konstruktora w definicji klasy doł

ą

czany jest 

konstruktor pusty (bez instrukcji)

background image

18

Programowanie obiektowe

Konstruktor domy

ś

lny

funkcja składowa , któr

ą

 mo

Ŝ

na wywoła

ć

 bez argumentów lub z 

domy

ś

lnymi warto

ś

ciami;

je

Ŝ

eli nie został zadeklarowany

Ŝ

aden konstruktor to kompilator 

doł

ą

cza pusty konstruktor domy

ś

lny:

Klasa :: Klasa() { };

je

Ŝ

eli zadeklarujemy konstruktor przeci

ąŜ

ony (z parametrami) to 

kompilator nie doł

ą

czy domy

ś

lnego bezparametrowego;

kolejno

ść

 wywoła

ń

 konstruktorów:

klasy bazowe w kolejno

ś

ci deklaracji,

obiektowe składowe klasy w kolejno

ś

ci deklaracji,

ciało konstruktora;

Konstruktory

background image

19

Programowanie obiektowe

Lista inicjalizacyjna konstruktora

słu

Ŝ

y do inicjowania składników klasy b

ę

d

ą

cych stałymi lub 

zmiennymi;

stanowi obej

ś

cie ograniczenia, 

Ŝ

e w definicji klasy zmienne i 

stałe nie mog

ą

 by

ć

 inicjalizowane (nie mo

Ŝ

na im nadawa

ć

 

warto

ś

ci pocz

ą

tkowych);

pojawia si

ę

 tylko przy definicji konstruktora, a nie przy jego 

deklaracji;

klasa::klasa(argumenty) : nazwa_stałej(warto

ść

 pocz

ą

tkowa)

[ , nazwa_stałej(warto

ść

 pocz

ą

tkowa)] 

// ciało konstruktora

};

Konstruktory

background image

20

Programowanie obiektowe

Lista inicjalizacyjna konstruktora – przykład 1

class Punkt

{

double x, y;

public:

// …

Punkt(): x(0.0), y(0.0)  { };

Punkt(double a, double b) : x(a), y(b) { };

};

Konstruktory

background image

21

Programowanie obiektowe

Lista inicjalizacyjna konstruktora – przykład 2

class abc
{

const double stala;
float x;
char c;

public:

abc(float pp, double dd, char znak);

};

...
abc::abc(float pp, double dd, char znak) : stala(dd), c(znak)
{

x=pp;

}

deklaracja konstruktora

Konstruktory

definicja konstruktora

background image

22

Programowanie obiektowe

Lista inicjalizacyjna konstruktora

umo

Ŝ

liwia inicjalizowanie zmiennych – tak jak w kodzie 

konstruktora; 

ponadto umo

Ŝ

liwia inicjalizowanie pól: referencji oraz stałych;

kolejno

ść

 inicjalizacji:

składowe w kolejno

ś

ci deklaracji,

ciało konstruktora;

Konstruktory

background image

23

Programowanie obiektowe

Lista inicjalizacyjna konstruktora – przykład 3

class Odcinek

{

Punkt p1;

Punkt p2;

Odcinek(double x1, double y1, double x2, double y2);

};

...

Odcinek::Odcinek(double x1, double y1, double x2, double y2): p1(x1, y1) 

{

p2 = Punkt(2.0, 2.0);

};

Konstruktory

• obiekt p1 – inicjowanie listą 
• obiekt p2 – inicjowanie konstruktorem (zadziałają dwa konstruktory!)

background image

24

Programowanie obiektowe

ostatnia funkcja wykonywana przed usuni

ę

ciem obiektu;

nazwa taka, jak nazwa klasy, ale poprzedzona tyld

ą

 „~”;

bez parametrów wej

ś

ciowych;

bez mo

Ŝ

liwo

ś

ci przeci

ąŜ

ania (jeden w klasie);

wywoływany automatycznie w momencie niszczenia obiektu 
(wychodzenia z bloku)

kolejno

ść

 wywoływania:

ciało destruktora;

destruktory obiektów składowych (kolejno

ść

 odwrotna do deklaracji 

w klasie);

destruktor klasy (klas) bazowych (kolejno

ść

 odwrotna do deklaracji 

w klasie); 

to, kiedy dokładnie likwidowane s

ą

 obiekty zale

Ŝ

y od konkretnego

kompilatora

Destruktory

background image

25

Programowanie obiektowe

Destruktor klasy „Klasa”:

~Klasa() { };

lub

~Klasa();

Klasa::~Klasa() { };

Przykład:

~Punkt() 

{cout << "Destruktor punktu x= " <<x << ", y= " << y << "\n"; }

~Odcinek() 

{ cout << "Destruktor odcinka \n"; }

Destruktory

background image

26

Programowanie obiektowe

Przykłady programowe

Konstruktory

Program 4.1a

Program 4.1b

C:\

C:\

background image

27

Programowanie obiektowe

Konstruktor klasy pochodnej

Lista inicjalizacyjna konstruktora

class KlasaA {

public:

KlasaA (int t)
{ ...};

};
class KlasaB : public KlasaA   

//deklaracja klasy pochodnej

{

public:

int x;
KlasaB (int par1, int par2) : KlasaA(par1), x(par2) 
{ ...
}; 

};

Konstruktory

background image

28

Programowanie obiektowe

Konstruktor klasy pochodnej

Lista inicjalizacyjna konstruktora

Na li

ś

cie musz

ą

 znale

źć

 si

ę

 konstruktory wszystkich klas 

bazowych;

Ich brak oznacza dla kompilatora konieczno

ść

 wywołania 

konstruktorów domy

ś

lnych z klas bazowych;

• Je

Ŝ

eli w klasie bazowej brak jest domy

ś

lnego konstruktora a s

ą

 

inne konstruktory, to zostanie wygenerowany bł

ą

d;

Kolejno

ść

 inicjalizacji:

• klasy bazowe (bezpo

ś

redni przodkowie w kolejno

ś

ci deklaracji),

• składowe w kolejno

ś

ci deklaracji,

• ciało konstruktora;

Konstruktory

background image

29

Programowanie obiektowe

Konstruktor klasy pochodnej - Przykład

class dorosly: public osoba 

{

char * nr_dowodu;

public:

void wczytaj ();

void wypisz ();

void ustaw(int wiek, char *p_imie, char *p_nazwisko, char *nr_dow);

dorosly(int k_wiek, char *p_imie, char *p_nazwisko, char *nr_dow) : 

osoba (wiek, p_imie, p_nazwisko), 

nr_dowodu(copy_string(nr_dow))  { };

};

Konstruktory

Program 4.2

background image

30

Programowanie obiektowe

Konstruktor jest zwykle deklarowany jako publiczny, bo przecieŜ
wprowadzane nim obiekty mogą być uŜywane przez klasy zewnętrzne

MoŜemy jednak dla konstruktora przewidzieć ochronę za pomocą etykiet
private 
lub protected

Wówczas jednak takŜe konstruowane obiekty będą dostępne tylko w obrębie 
klasy z tym konstruktorem jako private 
albo jako protected tylko w zakresie 
klas dziedzicz
ących.

Konstruktor moŜe zamiast definiować obiekty podawać kopie obiektów 
zawartych w innej klasie. Wtedy jest to tak zwany 

konstruktor kopiujący

.

Konstruktor moŜe dokonywać konwersji typu obiektu z jednego w drugi. 
Nazywamy go wtedy 

konstruktorem konwertującym

.

Konstruktory

background image

31

Programowanie obiektowe

Konstruktor i destruktor

dla obiektów zdefiniowanych w blokach programowych:

konstruktor jest wywoływany, gdy sterowanie napotyka kod definicji 
zmiennej – obiektu;

destruktory wywoływane po opuszczeniu bloku w kolejno

ś

ci 

odwrotnej do konstruktorów;

dla obiektów globalnych (statycznych):

konstruktory s

ą

 uaktywniane przed wywołaniem funkcji main(), 

w kolejno

ś

ci definicji;

destruktory s

ą

 uaktywniane po zako

ń

czeniu bloku main(), 

w kolejno

ś

ci odwrotnej;

dla obiektów dynamicznych:

po zastosowaniu operatora „new”: alokacja pami

ę

ci a potem 

wywołanie konstruktora;

po zastosowaniu „delete”: wywołanie destruktora i potem dealokacja
pami

ę

ci;

Destruktory

background image

32

Programowanie obiektowe

Przykłady programowe

Konstruktory i destruktory

Program 4.3

Program 4.4

background image

33

Programowanie obiektowe

Konstruktorem kopiującym  w  danej  klasie  jest  konstruktor,  który  moŜna 
wywołać z jednym argumentem typu referencja obiektu danej klasy:

klasa::klasa(klasa &)

Konstruktor  kopiujący  wprowadza  obiekty  identyczne  z  juŜ istniejącymi, 
czyli ich kopie (konstruowanie obiektu na podstawie wzoru).

Konstruktor kopiujący moŜe być wywołany niejawnie:

1.

W sytuacji gdy do funkcji jest przez wartość przesyłany obiekt klasy X. 
Wówczas tworzona jest kopia tego obiektu.

2.

W  sytuacji  kiedy  funkcja  zwraca  przez  wartość obiekt  klasy  X. 
Wtedy takŜe tworzona jest kopia obiektu.

To, Ŝe konstruktor kopiujący podaje obiekt kopiowany przez referencję daje 
mu moŜliwość zmiany zawartości obiektu klasy!! 

Konstruktor kopiujący

background image

34

Programowanie obiektowe

Przyjrzyjmy  się wywołaniu  konstruktora  klasy  o  nazwie  klasa,  którego 
argumentem jest referencja do obiektu danej klasy

klasa::klasa(klasa&)

Taki konstruktor nie konstruuje nowego obiektu tylko tworzy kopię innego, 
juŜ istniejącego obiektu danej klasy. 

Pozostałe argumenty konstruktora są domyślne. 

Przykłady konstruktorów kopiujących:

X::X(X&)

lub

X::X(X&, float=3.1415, int=0)

Konstruktor kopiujący

background image

35

Programowanie obiektowe

Nie  moŜna  pominąć referencji  w  konstruktorze  kopiującym,  bo  gdyby 
konstruktor  X  wywoływał obiekty  swojej  klasy  X  przez  wartość, czyli 
wytwarzałby swoją kopię, to powstaje nie zamknięta pętla tworzenia kopii. 

Konstruktor kopiujący moŜe uszkodzić oryginał!! 

Zabezpieczamy się przed taką sytuacją następująco:

X::X(const  X&obiekt)

Teraz  konstruktor  X  wie,  Ŝe  obiekt  klasy  X  musi  być wywoływany  jako 
stały. Konstruktor  kopiujący  jest  domyślnie  typu  const,  czyli  nie  moŜe 
zmienić sam siebie.

Konstruktor kopiujący

background image

36

Programowanie obiektowe

Przykład programowy

Program 4.5

Konstruktor kopiujący

background image

37

Programowanie obiektowe