PO W4 II ZIN


Wykład 4
Dziedziczenie
Konstruktory i destruktory
Programowanie obiektowe
1
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:
klasa bazowa
osoba
klasy pochodne
dziecko
dorosły
ka\dy dorosły i ka\de dziecko jest osobą (generalizacja);
dorosły jest przypadkiem szczególnym osoby, podobnie jak dziecko
(specjalizacja);
Programowanie obiektowe
2
Dziedziczenie
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);
Programowanie obiektowe
3
Dziedziczenie
sekcja docelowa dla składowych
dziedziczonych
Postać ogólna dziedziczenia:
class Klasa_pochodna: sekcja Klasa_bazowa_1 [, Klasa_bazowa_N]
{
// nowe składowe
// funkcje odziedziczone nadpisane (przedefiniowane)
};
tzw. dziedziczenie wielobazowe
Programowanie obiektowe
4
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
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();
};
Programowanie obiektowe
6
Przykład  klasa dorosly
Zało\enia rozszerzające dla klasy  dorosly :
numer dowodu:
char *nr_dowodu;
prywatny dla klasy  dorosly ;
metody wczytaj, wypisz, ustaw:
dostępne publicznie;
odziedziczone z klasy bazowej;
Programowanie obiektowe
7
Dziedziczenie
klasa pochodna
Klasa  dorosly
klasa bazowa
class dorosly: public osoba
{
sekcja docelowa dla składowych
dziedziczonych
char * nr_dowodu;
nowa składowa
public:
void wczytaj ();
void wypisz ();
void ustaw(int wiek, char *p_imie, char *p_nazwisko,
char *nr_dow);
};
metody odziedziczone ale przedefiniowane
Programowanie obiektowe
8
Dziedziczenie
sekcja docelowa dla składowych dziedziczonych:
class Klasa_pochodna : public Klasa_bazowa;
Klasa_bazowa Klasa_pochodna
// sekcja // sekcja
// public // public
// sekcja // sekcja
// protected // protected
// sekcja // sekcja
// private // private
dziedziczone ale niedostępne w klasie
pochodnej; dostępne poprzez
dziedziczone funkcje nieprywatne
Programowanie obiektowe
9
Dziedziczenie
sekcja docelowa dla składowych dziedziczonych:
class Klasa_pochodna : protected Klasa_bazowa;
Klasa_bazowa Klasa_pochodna
// sekcja // sekcja
// public // public
// sekcja // sekcja
// protected // protected
// sekcja // sekcja
// pivate // pivate
dziedziczone ale niedostępne w klasie
pochodnej; dostępne poprzez
dziedziczone funkcje nieprywatne
Programowanie obiektowe
10
Dziedziczenie
sekcja docelowa dla składowych dziedziczonych:
class Klasa_pochodna : private Klasa_bazowa;
Klasa_bazowa Klasa_pochodna
// sekcja // sekcja
// public // public
// sekcja // sekcja
// protected // protected
// sekcja // sekcja
// private // private
dziedziczone ale niedostępne w klasie
pochodnej; dostępne poprzez
dziedziczone funkcje nieprywatne
Programowanie obiektowe
11
Dziedziczenie
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 i public klasy bazowej mamy dostęp
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
trzeba je zdefiniować w klasie pochodnej
destruktory
Programowanie obiektowe
12
Dziedziczenie - podsumowanie
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 )
Programowanie obiektowe
13
Dziedziczenie
Przykład hierarchii klas
samochód  wywodzi się
autobus
osobowy
cię\arowy
Fiat VW opel
Programowanie obiektowe
14
Dziedziczenie - ograniczenia
Zgodność typów:
class KlasaA
{
&
}
class KlasaB: public KlasaA
{
....
};
KlasaA a;
zmienne obiektowe (obiekty)
KlasaB b;
dozwolone, ale kopiuje się tylko tyle, ile jest w KlasaA
a = b; // ?
niedozwolone
b = a; // ?
Programowanie obiektowe
15
Dziedziczenie
Zgodność typów:
KlasaA *ap;
wskazniki na obiekty
KlasaB *bp;
poprawne (wystąpi polimorfizm)
ap = bp; // ?
niedozwolone
bp = ap; // ?
dozwolone (styl języka C)
bp = (KlasaB*) ap; // ?
dozwolone (styl języka C++)
bp = dynamic_cast(ap); // ?
Operator dynamic_cast zwraca 0 (dla wskazników) lub zgłasza
bad_cast (dla referencji), gdy rzutowanie się nie powiedzie;
Programowanie obiektowe
16
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)
Programowanie obiektowe
17
Konstruktory
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;
Programowanie obiektowe
18
Konstruktory
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
};
Programowanie obiektowe
19
Konstruktory
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) { };
};
Programowanie obiektowe
20
Konstruktory
Lista inicjalizacyjna konstruktora  przykład 2
class abc
{
const double stala;
deklaracja konstruktora
float x;
char c;
public:
abc(float pp, double dd, char znak);
};
...
abc::abc(float pp, double dd, char znak) : stala(dd), c(znak)
{
definicja konstruktora
x=pp;
}
Programowanie obiektowe
21
Konstruktory
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;
Programowanie obiektowe
22
Konstruktory
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);
};
" obiekt p1  inicjowanie listą
" obiekt p2  inicjowanie konstruktorem (zadziałają dwa konstruktory!)
Programowanie obiektowe
23
Destruktory
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
Programowanie obiektowe
24
Destruktory
Destruktor klasy  Klasa :
~Klasa() { };
lub
~Klasa();
&
Klasa::~Klasa() { };
Przykład:
~Punkt()
{cout << "Destruktor punktu x= " <~Odcinek()
{ cout << "Destruktor odcinka \n"; }
Programowanie obiektowe
25
Konstruktory
Przykłady programowe
Program 4.1a
C:\
C:\ Program 4.1b
Programowanie obiektowe
26
Konstruktory
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)
{ ...
};
};
Programowanie obiektowe
27
Konstruktory
Konstruktor klasy pochodnej
Lista inicjalizacyjna konstruktora
Na liście muszą znalezć 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;
Programowanie obiektowe
28
Konstruktory
Konstruktor klasy pochodnej - Przykład
class dorosly: public osoba
{
char * nr_dowodu;
public:
Program 4.2
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)) { };
};
Programowanie obiektowe
29
Konstruktory
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.
Programowanie obiektowe
30
Destruktory
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;
Programowanie obiektowe
31
Konstruktory i destruktory
Przykłady programowe
Program 4.3
Program 4.4
Programowanie obiektowe
32
Konstruktor kopiujący
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!!
Programowanie obiektowe
33
Konstruktor kopiujący
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)
Programowanie obiektowe
34
Konstruktor kopiujący
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.
Programowanie obiektowe
35
Konstruktor kopiujący
Przykład programowy
Program 4.5
Programowanie obiektowe
36
Programowanie obiektowe
37


Wyszukiwarka

Podobne podstrony:
PO W4 IV ZIN
PO W3 II ZIN
PO W1 2 II ZIN
PO W3 II ZIN
PO W7 8 II ZIN
PO W 5 6 II ZIN
Matematyka krok po kroku II
PO W2 IV ZIN
PO W3 IV ZIN
(Ekumenizm przed i po Soborze Watykańskim II)
02 Stalinizacja życia w Polsce po II Wojnie Światowej
Zimna wojna, konferencje, sprawa niemiec po II wojnie swiatowej
Slowo Abp A Dzięgi po Beatyfikacji JP II
Świat po II Wojnie Światowej, prezentacja

więcej podobnych podstron