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

Slides:



Advertisements
Podobne prezentacje
Funkcje w PHP ABK.
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
Programowanie obiektowe
Deklaracje i definicje klas w C++ Składowe, pola, metody Konstruktory
Klasa listy jednokierunkowej Przekazywanie parametrów do funkcji
Programowanie obiektowe
Programowanie obiektowe PO PO - LAB 4 Wojciech Pieprzyca.
Programowanie obiektowe
Klasy i obiekty.
Metody wirtualne.
Wzorce.
Prowadzący: mgr inż. Elżbieta Majka
Static, const, volatile.
Dziedziczenie. Po co nam dziedziczenie? class osoba { char * imie, char * imie, * nazwisko; * nazwisko;public: void wypisz_imie(); void wypisz_imie();
ODE Triggery. Wstęp n Triggery są trójką zdarzenie-warunek-akcja (event-condition- action). n Zdarzenia mogą być proste lub złożone, co zostanie omówione.
ODE Informacje wstępne. Pojęcia podstawowe n Obiektowa baza danych u język komunikacji u ziarnistość obiektów u identyfikacja obiektów n Transakcja -
Repetitio est mater studiorum
Struktury.
Tablice.
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Tablice tablica jest sekwencją elementów tego samego typu (prostego lub obiektowego) w Javie tablice są obiektami, a zmienne tablicowe przechowują referencję
Podstawy programowania II
Podstawy informatyki 2013/2014
T: Różnice pomiędzy programowaniem strukturalnym a obiektowym
Programowanie obiektowe III rok EiT
Jerzy F. Kotowski1 Informatyka I Wykład 14 DEKLARATORY.
Programowanie obiektowe III rok EiT
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Prasek Aneta, Skiba Katarzyna. Funkcje stałe const to takie funkcje, które nie mogą modyfikować stanu obiektu. Oznacza to, że funkcja stała nie może zmieniać.
Kurs języka C++ – wykład 3 ( )
Kurs języka C++ – wykład 9 ( )
Programowanie w języku C++
Kurs języka C++ – wykład 5 ( )
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie strukturalne i obiektowe C++
Kurs języka C++ – wykład 4 ( )
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
This, friend, operatory. this dostępny w każdej niestatycznej metodzie dostępny w każdej niestatycznej metodzie jest to wskaźnik do obiektu na rzecz którego.
Paweł Starzyk Obiektowe metody projektowania systemów
Dziedziczenie wielobazowe. dana klasa może mieć kilka bezpośrednich klas bazowych: dana klasa może mieć kilka bezpośrednich klas bazowych: kolorpołożenie.
Dziedziczenie Wykład 7 Dziedziczenie sekwencyjne
Wykład 4 Klasa Vec, której konstruktory alokują pamięć dla obiektów 1.Przykład definicji klasy Vec 2.Definicje konstruktorów i destruktora 3.Definicja.
PO13-1 / 19 Wykład 13 Wyjątki i ich zgłaszanie Wyłapywanie wyjątków Obsługa wyjątków Wykorzystanie polimorfizmu Filtrowanie wyjątków Błędy w konstruktorach.
Wykład 5 Klasa Vec i jej operatory 1.Kategorie operatorów 2.Operatory ogólne - przykłady 3.Operatory specjalne [ ], ( ) oraz –> 4.Operatory new i delete.
Wykład 8 Polimorfizm 1.Funkcje polimorficzne 2.Czyste funkcje wirtualne i klasy abstrakcyjne PO8-1 / 38.
Podstawy informatyki Tablice Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Podstawy informatyki Funkcje Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego Matuszyka Podstawy.
Podstawy informatyki Struktury Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi.
Podstawy informatyki Mechanizm obsługi sytuacji wyjątkowych Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
C++ mgr inż. Tomasz Turba Politechnika Opolska 2016.
Programowanie Obiektowe – Wykład 6
Kurs języka C++ – wykład 3 ( )
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Kurs języka C++ – wykład 4 ( )
Język C++ Typy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Język C++ Tablice Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Zapis prezentacji:

Konstruktory i Destruktory

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?

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

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

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.

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

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

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

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

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 }

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.

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 !!!

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.

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

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

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.

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

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

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) {}

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

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”;}

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 …

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)

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

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

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;

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

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

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

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

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

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

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

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

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

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