Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Konstruktory i Destruktory. Konstruktor Konstruktor — co to? Konstruktor — co to? jest metodą służącą do inicjowania obiektów danej klasy jest metodą.

Podobne prezentacje


Prezentacja na temat: "Konstruktory i Destruktory. Konstruktor Konstruktor — co to? Konstruktor — co to? jest metodą służącą do inicjowania obiektów danej klasy jest metodą."— Zapis prezentacji:

1 Konstruktory i Destruktory

2 Konstruktor Konstruktor — co to? Konstruktor — co to? jest metodą służącą do inicjowania obiektów danej klasy jest metodą służącą do inicjowania obiektów danej klasy jest przepisem na utworzenie obiektu danego typu jest przepisem na utworzenie obiektu danego typu Konstruktor — czy jest potrzebny? Konstruktor — czy jest potrzebny? czy dane zawarte w obiekcie wymagają inicjalizacji? czy dane zawarte w obiekcie wymagają inicjalizacji?

3 Konstruktor — deklarowanie Deklaracja konstruktora dla klasy T: Deklaracja konstruktora dla klasy T: T(args); lub T::T(args); class point { double x, y; public: // … point(double, double);// nie zwraca nawet void point(double);// można go przeciążać point(); };

4 Konstruktor — nietypowa metoda Nie wolno określać typu wartości zwracanej (nawet void). Nie wolno określać typu wartości zwracanej (nawet void). Nie można wywołać konstruktora na rzecz już istniejącego obiektu. Nie można wywołać konstruktora na rzecz już istniejącego obiektu. Nie można pobrać adresu konstruktora. Nie można pobrać adresu konstruktora. Nie jest widoczny w zakresie klasy i nie ma nazwy (wg. opisu języka). Nie jest widoczny w zakresie klasy i nie ma nazwy (wg. opisu języka).

5 Wywoływanie Konstruktor bezargumentowy (domyślny): Konstruktor bezargumentowy (domyślny): point p1; Pozostałe: Pozostałe: point p3(10.0, 20.0); // 2 arg. point p2(1.0);// 1 arg. // point p1(); // tak wygląda deklaracja funkcji p1 point p2=1.0;// tak tylko dla k. 1 arg.

6 Wywoływanie można jawnie określić konstruktor można jawnie określić konstruktor point p3=point(10.0, 20.0); point p2=point(1.0); point p1=point(); albo: point p3=point::point(10.0, 20.0); point p3=point::point(1.0); point p1=point::point();

7 Wywoływanie obiekty anonimowe obiekty anonimowe point pu;// obiekt nieanonimowy pu pu = point (3); // tymczasowy obiekt anonimowy, // usunięcie (zaraz po przypisaniu lub // później, „gdy będzie niepotrzebny”) point(20); // tymczasowy anonimowy i bezużyteczny point * ppu; ppu=&point(); // błąd trudny do wyśledzenia, składniowo poprawne

8 Definiowanie class point { double x, y; public: // … point(double, double); point(double); point() {x=y=0.0; }; }; inline point::point(double d) { x=y=d; } point::point(double x0, double y0) { x=x0; y=y0; }

9 Lista inicjacyjna w definicji konstruktora (i tylko tu) można wykorzystać listę inicjacyjną w definicji konstruktora (i tylko tu) można wykorzystać listę inicjacyjną T() : składowa(inicjalizator) [, składowa(inicjalizator) …] { } class point { double x, y; public: // … point():x(0.0), y(0.0) {}; };

10 Lista inicjacyjna inline point::point(double d) :x(d), y(d) { // zrobione } point::point(double x, double y) :x(x), y(y)// to jest jednoznaczne !!! { // zrobione }

11 Lista inicjacyjna tylko tak można inicjalizować pola będące referencjami i pola ustalone. tylko tak można inicjalizować pola będące referencjami i pola ustalone. w liście inicjacyjnej oprócz niestatycznych składowych klasy (zadeklarowanych w klasie, a nie odziedziczonych) można określić sposób wywołania konstruktorów bezpośrednich przodków i przodków wirtualnych. w liście inicjacyjnej oprócz niestatycznych składowych klasy (zadeklarowanych w klasie, a nie odziedziczonych) można określić sposób wywołania konstruktorów bezpośrednich przodków i przodków wirtualnych. kolejność na liście inicjacyjnej nie ma znaczenia, wykonywanie w kolejności: klasy bazowe (wirtualne i bezpośredni przodkowie w kolejności deklaracji), składowe w kolejności deklaracji, ciało konstruktora. kolejność na liście inicjacyjnej nie ma znaczenia, wykonywanie w kolejności: klasy bazowe (wirtualne i bezpośredni przodkowie w kolejności deklaracji), składowe w kolejności deklaracji, ciało konstruktora.

12 Lista inicjacyjna point::point(int x, int y):x(x), y(y) {}; //OK. inline point::point(int i) :x(i), y(x) {}; //OK. inline point::point(int i) :y(x), x(i) {}; //OK. // point::point(int i) :y(i), x(y) {} — oops !!!

13 Konstruktor domyślny jeżeli żaden konstruktor nie został zadeklarowany to kompilator dostarcza domyślny konstruktor (bezargumentowy) o pustym ciele, dla klasy T: jeżeli żaden konstruktor nie został zadeklarowany to kompilator dostarcza domyślny konstruktor (bezargumentowy) o pustym ciele, dla klasy T:T::T(){} jeżeli my zadeklarujemy konstruktor (nawet tylko argumentowy) to kompilator nie dostarczy domyślnego bezargumentowego. jeżeli my zadeklarujemy konstruktor (nawet tylko argumentowy) to kompilator nie dostarczy domyślnego bezargumentowego.

14 Kolejność wywoływania konstruktorów Konstruktory Konstruktory 1. klasa (klasy) bazowa (bazowe w kolejności deklaracji) 2. składowe klasy w kolejności deklaracji 3. ciało konstruktora Uwaga: obiektowe składowe klasy (oraz klasy bazowe), jeżeli nie zostaną zainicjalizowane w liście inicjacyjnej, to będą inicjalizowane 2 razy: Uwaga: obiektowe składowe klasy (oraz klasy bazowe), jeżeli nie zostaną zainicjalizowane w liście inicjacyjnej, to będą inicjalizowane 2 razy: 1. konstruktorem bezargumentowym swojej klasy 2. następnie kodem z ciała konstruktora tworzonego obiektu

15 Przykład class segment { point p1; int number; point p2; }; segment::segment()// jak to zadziała??? :p1(1.0, 1.0) {p2=point(1.0);};

16 Przykład class segment { point p1; int number; point p2; };segment::segment() :p1(1.0, 1.0)// konstr. p1 (2-arg), konstr. p2 (domyślny) {// number niezainicjalizowany p2=point(1.0);// konstr. temp. (1 arg.), przypisanie };// destr. temp.

17 Konstruktor kopiujący służy do inicjalizacji obiektów danej klasy innymi obiektami tej samej klasy, dla klasy T ma postać: służy do inicjalizacji obiektów danej klasy innymi obiektami tej samej klasy, dla klasy T ma postać: T::T(const T &); parametr musi być referencją, a nie zmienną (bo powstawałyby obiekty tymczasowe, które też trzeba zainicjalizować, też konstruktorem kopiującym) parametr musi być referencją, a nie zmienną (bo powstawałyby obiekty tymczasowe, które też trzeba zainicjalizować, też konstruktorem kopiującym) parametr powinien być const aby można było wywołać konstruktor z argumentem const parametr powinien być const aby można było wywołać konstruktor z argumentem const

18 Konstruktor kopiujący np. k.k. dla klasy point: np. k.k. dla klasy point: point(const point & p) :x(p.x), y(p.y) {} Konstruktorem kopiującym może być też inny kostruktor który można wywołać w taki sposób, np.: Konstruktorem kopiującym może być też inny kostruktor który można wywołać w taki sposób, np.: point(const point &, int=7);

19 Konstruktor kopiujący generowany automatycznie K.k. jest generowany automatycznie przez kompilator, gdy nie programista go nie zdefiniuje (inne konstruktory są nieistotne). K.k. jest generowany automatycznie przez kompilator, gdy nie programista go nie zdefiniuje (inne konstruktory są nieistotne). generowany automatycznie k.k. skopiuje obiekt pole po polu generowany automatycznie k.k. skopiuje obiekt pole po polu (klasy bazowe oraz pola obiektowe ich konstruktorami kopiującymi – analogicznie jak dla listy inicjalizacyjnej będzie to działać też gdy klasa ma składowe ustalone (const)) np.: point(const point & p) :x(p.x), y(p.y) {}

20 Destruktor Co to jest destruktor? Co to jest destruktor? łatwo zgadnąć łatwo zgadnąć Kiedy jest przydatny? Kiedy jest przydatny? jeszcze łatwiej jeszcze łatwiej

21 Destruktor Destruktor klasy T: Destruktor klasy T: ~T(); np.: np.: ~point() // nie ma argumentów ani typu zwracanego { cout << ”\njestem sobie point (x:” << x << „ y:” << y; << x << „ y:” << y; <<„) a zaraz mnie już nie będzie”; <<„) a zaraz mnie już nie będzie”;}

22 Destruktor przeciwnie do konstruktora jest widoczny w zakresie klasy przeciwnie do konstruktora jest widoczny w zakresie klasy destruktor można wywołać jawnie destruktor można wywołać jawnie destruktor domyślny – generowany gdy nie zdefiniowano destruktora destruktor domyślny – generowany gdy nie zdefiniowano destruktora ma ciało puste, ale … ma ciało puste, ale …

23 Kolejność wywoływania konstruktorów i destruktorów Konstruktory Konstruktory 1. klasa (klasy) bazowa (bazowe w kolejności deklaracji) 2. składowe klasy w kolejności deklaracji 3. ciało konstruktora Destruktory – po prostu odwrotnie Destruktory – po prostu odwrotnie 1. ciało destruktora 2. destruktory obiektów składowych (kolejność przeciwna do deklaracji w klasie) 3. destruktor klasy (klas) bazowych (kolejność przeciwna do deklaracji w klasie)

24 Kolejność wywoływania konstruktorów i destruktorów obiekty zdefiniowane w blokach (lokalne, automatyczne) obiekty zdefiniowane w blokach (lokalne, automatyczne) konstruktory są wywoływane gdy sterowanie napotyka na definicję obiektu konstruktory są wywoływane gdy sterowanie napotyka na definicję obiektu destruktory po opuszczeniu bloku w kolejności odwrotnej do konstruktorów destruktory po opuszczeniu bloku w kolejności odwrotnej do konstruktorów obiekty globalne (statyczne) obiekty globalne (statyczne) konstruktory w kolejności definicji, przed wywołaniem funkcji main() konstruktory w kolejności definicji, przed wywołaniem funkcji main() destruktory w kolejności odwrotnej, po zakończeniu main(). destruktory w kolejności odwrotnej, po zakończeniu main().

25 Kolejność wywoływania konstruktorów i destruktorów obiekty dynamiczne kontrolowane są przez programistę za pomocą new i delete. obiekty dynamiczne kontrolowane są przez programistę za pomocą new i delete. przydział pamięci i wywołanie konstruktora w momencie zastosowania operatora new przydział pamięci i wywołanie konstruktora w momencie zastosowania operatora new destruktor i dealokacja po delete destruktor i dealokacja po delete

26 Konstrukcja i destrukcja obiektów dynamicznych point *pp0=new point; point *pp1=new point(1.0); point *pp2=new point(10.0, 20.0); point *tablica=new point[10]; // tablica 10 punktow // inicjalizowanych konstr. bezarg. // w kolejności rosnących adresów // przy new T[] wyłącznie konstruktor bezargumentowy delete pp1; delete pp2; delete pp0; delete [] tablica;

27 Przykład point global=777; int f(int) { segment o; } void main() { point local; point *p_local; local=global;local=point(10,20); int a=f(1); for (int i=0; i<2; i++) { point w_bloku=local; point w_bloku=local; } p_local = new point(1.0); point local2(10,20); delete p_local; p_local = new point(); }

28 Przykład point global=777; int f(int) { segment o; }k4, k5, d5, d4 k1 void main() { point local;k2 point *p_local; local=global; local=point(10,20); k3, d3 int a=f(1); for (int i=0; i<2; i++) { point w_bloku=local;k6, i==1 k7 point w_bloku=local;k6, i==1 k7 }d6, i==1 d7 }d6, i==1 d7 p_local = new point(1.0);k8 point local2(10,20);k9 delete p_local;d8 p_local = new point();k10 }d9, d2, d1, ???10

29 Przykład zdefiniować klasę person opisującą osoby zdefiniować klasę person opisującą osoby class person { int age;// wiek int age;// wiek char *name,// imię char *name,// imię *lastName;// nazwisko *lastName;// nazwiskopublic: person(const char *name, const char *lastName, const int age); person(const char *name, const char *lastName, const int age); person(const person & o); person(const person & o); ~person(); ~person();};

30 inline person::person(const char *name, const char *lastName, const int age) :age(age) { person::name=new char[strlen(name) + 1]; person::name=new char[strlen(name) + 1]; strcpy(person::name, name); strcpy(person::name, name); person::lastName=new char[strlen(lastName) + 1]; person::lastName=new char[strlen(lastName) + 1]; strcpy(person::lastName, lastName); strcpy(person::lastName, lastName);} inline person::person(const person & o) :age(o.age), name(new char[strlen(o.name) + 1]), lastName(new char[strlen(o.lastName) + 1]) { strcpy(name, o.name); strcpy(name, o.name); strcpy(lastName, o.lastName); strcpy(lastName, o.lastName);} Przykład

31 inline person::~person() { delete [] name; delete [] name; delete [] lastName; delete [] lastName;} Przykład

32 Przykład zdefiniować klasę queue reprezentującą kolejkę osób (FIFO) zdefiniować klasę queue reprezentującą kolejkę osób (FIFO) class queue { person **persons; // tablica wskaźników do osób w kolejce person **persons; // tablica wskaźników do osób w kolejce const int capacity;// pojemność kolejki const int capacity;// pojemność kolejki int length;// aktualna długość kolejki int length;// aktualna długość kolejkipublic: queue(int capacity); queue(int capacity); ~queue(); ~queue(); int insert(const person &o); // wstaw, 1-brak miejsca, 0-wstawiono int insert(const person &o); // wstaw, 1-brak miejsca, 0-wstawiono int collect(person &o); // pobierz, 1-kolejka pusta, 0-pobrano int collect(person &o); // pobierz, 1-kolejka pusta, 0-pobrano};

33 queue::queue(int capacity) :capacity(capacity), length(0), persons(new (person*) [capacity]) {}queue::~queue(){ for (int i=0; i<length; i++) for (int i=0; i<length; i++) delete persons[i];// elementy delete persons[i];// elementy delete [] persons;// tablica delete [] persons;// tablica} Przykład

34 int queue::insert(const person &o) { if (length==capacity) if (length==capacity) return 1; return 1; persons[length++]=new person(o); // tworzymy kopie argumentu metody persons[length++]=new person(o); // tworzymy kopie argumentu metody return 0; return 0;} Przykład

35 int queue::collect(person &o) { if (length==0) if (length==0) return 1; return 1; o.~person(); // jeszcze nie wiemy o.~person(); // jeszcze nie wiemy o=*persons[0]; // jak przeciążyć operator przypisania o=*persons[0]; // jak przeciążyć operator przypisania length--; length--; for(int i=0; i<length; i++) for(int i=0; i<length; i++) persons[i]=persons[i+1]; persons[i]=persons[i+1]; return 0; return 0;} Przykład

36 int queue::collect(person &o) { if (length==0) if (length==0) return 1; return 1; o.~person(); // jeszcze nie wiemy o.~person(); // jeszcze nie wiemy o=*persons[0]; // jak przeciążyć operator przypisania o=*persons[0]; // jak przeciążyć operator przypisania length--; length--; for(int i=0; i<length; i++) for(int i=0; i<length; i++) persons[i]=persons[i+1]; persons[i]=persons[i+1]; return 0; return 0;} // wytęż wzrok i znajdź wyciek pamięci !!! Przykład


Pobierz ppt "Konstruktory i Destruktory. Konstruktor Konstruktor — co to? Konstruktor — co to? jest metodą służącą do inicjowania obiektów danej klasy jest metodą."

Podobne prezentacje


Reklamy Google