background image

Wykład 4

Dziedziczenie

Konstruktory i destruktory

Programowanie obiektowe

1

Konstruktory i destruktory

background image

Dziedziczenie

Dziedziczenie to technika pozwalaj

ą

ca na definiowanie nowych klas przy 

wykorzystaniu klas wcze

ś

niej zdefiniowanych

Wyra

Ŝ

a zwi

ą

zki hierarchiczne mi

ę

dzy klasami (klasa nadrz

ę

dna - klasa 

podrz

ę

dna);

Specjalizuje lub generalizuje klasy;

Przykład:

osoba

klasa bazowa

Programowanie obiektowe

2

Przykład:

ka

Ŝ

dy dorosły i ka

Ŝ

de dziecko jest osob

ą

 (generalizacja);

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

dziecko

dorosły

klasy pochodne

background image

Klasa pochodna:

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

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

Dziedziczenie

Programowanie obiektowe

3

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);

background image

Posta

ć

 ogólna dziedziczenia:

class Klasa_pochodna: sekcja Klasa_bazowa_1 [, Klasa_bazowa_N]

{

Dziedziczenie

sekcja docelowa dla składowych 

dziedziczonych

Programowanie obiektowe

4

// nowe składowe

// funkcje odziedziczone nadpisane (przedefiniowane)

};

tzw. dziedziczenie wielobazowe

background image

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 (::)

Programowanie obiektowe

5

jest mo

Ŝ

liwe z u

Ŝ

yciem operatora zakresu (::)

background image

Przykład – klasa osoba

class osoba
{

int wiek;
char imi

ę

[20], nazwisko[30];

public:

void wczytaj(); 

Programowanie obiektowe

6

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

ę

, char *p_nazwisko);

void wypisz();

}; 

background image

Zało

Ŝ

enia rozszerzaj

ą

ce dla klasy „dorosly”:

numer dowodu:

char *nr_dowodu;

prywatny dla klasy „dorosly”;

Przykład – klasa dorosly

Programowanie obiektowe

7

prywatny dla klasy „dorosly”;

metody wczytajwypiszustaw:

dost

ę

pne publicznie;

odziedziczone z klasy bazowej;

background image

Klasa „dorosly”

class dorosly: public osoba 
{

klasa pochodna

klasa bazowa

sekcja docelowa dla składowych 

dziedziczonych

Dziedziczenie

Programowanie obiektowe

8

char * nr_dowodu;

public:

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

char *nr_dow); 

};

dziedziczonych

nowa składowa

metody odziedziczone ale przedefiniowane

background image

sekcja docelowa dla składowych dziedziczonych:

class Klasa_pochodna : 

public

Klasa_bazowa; 

Klasa_bazowa

// sekcja

// public

Klasa_pochodna

// sekcja

// public

Dziedziczenie

Programowanie obiektowe

9

// public

// sekcja

// protected

// sekcja

// private

// public

// sekcja

// protected

// sekcja

// private

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

background image

sekcja docelowa dla składowych dziedziczonych:

class Klasa_pochodna : 

protected

Klasa_bazowa;

Klasa_bazowa

// sekcja

// public

Klasa_pochodna

// sekcja

// public

Dziedziczenie

Programowanie obiektowe

10

// public

// sekcja

// protected

// sekcja

// pivate

// public

// sekcja

// protected

// sekcja

// pivate

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

background image

sekcja docelowa dla składowych dziedziczonych:

class Klasa_pochodna : 

private

Klasa_bazowa; 

Klasa_bazowa

// sekcja

// public

Klasa_pochodna

// sekcja

// public

Dziedziczenie

Programowanie obiektowe

11

// public

// sekcja

// protected

// sekcja

// private

// public

// sekcja

// protected

// sekcja

// private

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

background image

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

Programowanie obiektowe

12

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

trzeba je zdefiniować w klasie pochodnej

background image

Dziedziczenie jest technik

ą

 definiowania nowych klas;

Dziedziczenie jest jedn

ą

 z najwspanialszych cech j

ę

zyków 

programowania obiektowego;

Umo

Ŝ

liwia:

Dziedziczenie - podsumowanie

Programowanie obiektowe

13

Umo

Ŝ

liwia:

oszcz

ę

dno

ść

 pracy,

tworzenie hierarchii klas (hierarchia wprowadza naturalne relacje 
mi

ę

dzy klasami),

tworzenie szablonów klas (klas ogólnych), tzn. klas 
przeznaczonych do dziedziczenia , np. szablon klasy „kolejka”)

background image

Przykład hierarchii klas

Dziedziczenie

samochód

„wywodzi się”

Programowanie obiektowe

14

osobowy

cięŜarowy

autobus

Fiat

VW

opel

background image

Zgodno

ść

 typów:

class KlasaA
{

}
class KlasaB: public KlasaA 
{

Dziedziczenie - ograniczenia

Programowanie obiektowe

15

{

....

};

KlasaA  a;
KlasaB  b;

a = b; // ?

b = a; // ?

dozwolone, ale kopiuje si

ę

 tylko tyle, ile jest w KlasaA

niedozwolone 

zmienne obiektowe (obiekty)

background image

Zgodno

ść

 typów:

KlasaA *ap;
KlasaB *bp;     

ap = bp;

// ?

poprawne (wyst

ą

pi polimorfizm

Dziedziczenie

wska

ź

niki na obiekty

Programowanie obiektowe

16

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;

niedozwolone

dozwolone (styl j

ę

zyka C)

dozwolone (styl j

ę

zyka C++)

background image

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 przydzielane jest dla niego 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”;

Programowanie obiektowe

17

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

Konstruktor domy

ś

lny

funkcja składowa, któr

ą

 mo

Ŝ

na wywoła

ć

 bez argumentów 

lub z warto

ś

ciami domy

ś

lnymi;

je

Ŝ

eli nie został zadeklarowany

Ŝ

aden konstruktor to kompilator 

doł

ą

cza pusty konstruktor domy

ś

lny:

Konstruktory

Programowanie obiektowe

18

Klasa :: Klasa() { };

je

Ŝ

eli zadeklarujemy konstruktor przeci

ąŜ

ony (z parametrami) to 

kompilator nie doł

ą

czy pustego konstruktora domy

ś

lnego;

kolejno

ść

 wywoła

ń

 konstruktorów:

klasy bazowe w kolejno

ś

ci deklaracji,

obiektowe składowe klasy w kolejno

ś

ci deklaracji,

ciało konstruktora;

background image

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 

Konstruktory

Programowanie obiektowe

19

pojawia si

ę

 tylko przy definicji konstruktora, a nie przy jego 

deklaracji;

kolejno

ść

 inicjalizacji:

składowe w kolejno

ś

ci wymienienia na li

ś

cie,

ciało konstruktora

klasa::klasa(argumenty) : nazwa_pola(warto

ść

 pocz

ą

tkowa)

[ , nazwa_pola(warto

ść

 pocz

ą

tkowa)] 

// ciało konstruktora

};

background image

Lista inicjalizacyjna konstruktora – przykład 1

class Punkt

{

Konstruktory

Programowanie obiektowe

20

double x, y;

public:

// …

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

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

};

background image

Lista inicjalizacyjna konstruktora – przykład 2

class abc
{

const double stala;
float x;

deklaracja konstruktora

Konstruktory

Programowanie obiektowe

21

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;

}

definicja konstruktora

background image

Lista inicjalizacyjna konstruktora – przykład 3

class Odcinek

{

Punkt p1;

Punkt p2;

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

Konstruktory

Programowanie obiektowe

22

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);

};

• obiekt p1 – inicjowanie listą inicjalizacyjną
• obiekt p2 – inicjowanie w ciele konstruktora 

background image

ostatnia funkcja wykonywana przed usuni

ę

ciem obiektu;

nazwa taka sama, 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 

Destruktory

Programowanie obiektowe

23

(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

background image

Destruktor klasy „Klasa”:

~Klasa() {... };

lub

~Klasa();

Klasa::~Klasa() {... };

Destruktory

Programowanie obiektowe

24

Klasa::~Klasa() {... };

Przykład:

~Punkt() 

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

~Odcinek() 

{ cout << "Destruktor odcinka <<endl; }

background image

Przykłady programowe

Konstruktory

Program 3.1a

C:\

Programowanie obiektowe

25

Program 3.1b

C:\

background image

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;

Konstruktory

Programowanie obiektowe

26

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;

background image

Konstruktor klasy pochodnej

Lista inicjalizacyjna konstruktora

class KlasaA {

...
public:

KlasaA (int t)

Konstruktory

Programowanie obiektowe

27

KlasaA (int t)
{ ...};

};
class KlasaB : public KlasaA   

//deklaracja klasy pochodnej

{

public:

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

};

background image

Konstruktor klasy pochodnej - Przykład

class dorosly: public osoba 

{

char * nr_dowodu;

public:

Konstruktory

Programowanie obiektowe

28

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 (k_wiek, p_imie, p_nazwisko), 

nr_dowodu(kopiuj(nr_dow))  { };

Program 3.2

background image

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 

Konstruktory

Programowanie obiektowe

29

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

.

background image

Konstruktor i destruktor

dla obiektów zdefiniowanych w blokach programowych:

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

destruktory s

ą

 wywoływane po opuszczeniu bloku w kolejno

ś

ci 

odwrotnej do konstruktorów;

dla obiektów globalnych (statycznych):

Konstruktory i destruktory

Programowanie obiektowe

30

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 do definicji;

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;

background image

Przykłady programowe

Konstruktory i destruktory

Program 3.3

C:\

Programowanie obiektowe

31

Program 3.4

C:\

background image

Programowanie obiektowe

32