Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski.

Slides:



Advertisements
Podobne prezentacje
C++ wykład 2 ( ) Klasy i obiekty.
Advertisements

C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
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.
Standardowa biblioteka języka C++
Programowanie obiektowe
Wzorce.
Static, const, volatile.
Dziedziczenie. Po co nam dziedziczenie? class osoba { char * imie, char * imie, * nazwisko; * nazwisko;public: void wypisz_imie(); void wypisz_imie();
Bezpieczeństwo wyjątków w C++: OpenGL
Programowanie obiektowe w Javie
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.
Struktury.
Tablice.
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Podstawy programowania
Języki programowania obiektowego
Podstawy programowania II
Programowanie obiektowe III rok EiT
Jerzy F. Kotowski1 Informatyka I Wykład 11 STRUKTURY I UNIE.
Podstawy programowania
Programowanie obiektowe w C++
Programowanie obiektowe III rok EiT
Jerzy F. Kotowski1 Informatyka I Wykład 14 DEKLARATORY.
Programowanie obiektowe – zastosowanie języka Java SE
JAVA c.d.. Instrukcji wyboru SWITCH używamy, jeśli chcemy w zależności od wartości pewnego wyrażenia wykonać jeden z kilku fragmentów kodu. Jest to w.
Programowanie obiektowe III rok EiT dr inż. Jerzy Kotowski Wykład IX.
Programowanie obiektowe III rok EiT
Andrzej Repak Nr albumu
Java – coś na temat Klas Piotr Rosik
Inicjalizacja i sprzątanie
Programowanie obiektowe
Programowanie obiektowe Wykład 7 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/20 Dariusz Wardowski.
Programowanie obiektowe Wykład 6 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14 Dariusz Wardowski.
Kurs języka C++ – wykład 3 ( )
Kurs języka C++ – wykład 9 ( )
Treści multimedialne - kodowanie, przetwarzanie, prezentacja Odtwarzanie treści multimedialnych Andrzej Majkowski informatyka +
Programowanie strukturalne i obiektowe C++
Programowanie strukturalne i obiektowe C++
Zmienne i typy danych w C#
Kurs języka C++ – wykład 4 ( )
K URS JĘZYKA C++ – WYKŁAD 2 ( ) Klasy i obiekty.
Programowanie obiektowe Wykład 9 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/15 Dariusz Wardowski.
Konstruktory i Destruktory. Konstruktor Konstruktor — co to? Konstruktor — co to? jest metodą służącą do inicjowania obiektów danej klasy jest metodą.
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 2 Klasa Zesp i jej hermetyzacja 1.Przykład definicji klasy Zesp 2.Zmiana definicji klasy 3.Zmienne i funkcje statyczne PO2-1 / 28.
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.
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.
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.
Programowanie Obiektowe – Wykład 6
Kurs języka C++ – wykład 3 ( )
Klasy, pola, obiekty, metody. Modyfikatory dostępu, hermetyzacja
(według:
Delegaty Delegat to obiekt „wiedzący”, jak wywołać metodę.
Programowanie Obiektowe – Wykład 2
Kurs języka C++ – wykład 4 ( )
Programowanie obiektowe
Programowanie obiektowe
Programowanie obiektowe – zastosowanie języka Java SE
Język C++ Typy Łukasz Sztangret Katedra Informatyki Stosowanej i Modelowania Prezentacja przygotowana w oparciu o materiały Danuty Szeligi i Pawła Jerzego.
Zapis prezentacji:

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 2/21 Przydzielanie pamięci Poniżej przedstawiono w C++ dwie klasy obrazujące sposób rezerwacji pamięci. class Osoba { private: char imie[30]; char nazwisko[30]; int wiek; public: Osoba(){} Osoba(char i[], char n[], int w); }; Osoba::Osoba(char i[], char n[], int w) { strcpy(imie,i); strcpy(nazwisko,n); wiek = w; } class Osoba { private: char* imie; char* nazwisko; int wiek; public: Osoba(); Osoba(char* i, char* n, int w); ~Osoba(); }; Osoba::Osoba() {imie = new char[1]; imie[1]=\0; nazwisko = new char[1]; nazwisko[1]=0; } Osoba::Osoba(char* i, char* n, int w) { imie = new char[strlen(i)+1]; strcpy(imie,i); nazwisko = new char[strlen(n)+1]; strcpy(nazwisko,n); wiek = w; } Osoba::~Osoba() { delete [] imie; delete [] nazwisko; }

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 3/21 Pamięć dynamiczna – new i delete Do zaalokowania pamięci w sposób dynamiczny używamy operatoa new. Zastosowanie tego operatora wiąże się jednak z podjęciem dodatkowych czynności takich jak rozbudowanie destruktora klasy oraz zsynchronizowanie rezerwacji pamięci w konstruktorach z jej zwolnieniem w destruktorze za pomocą operatora delete. W przypadku dynamicznego przydzielania pamięci konieczne jest również utworzenie odpowiednich metod, które będą obsługiwały inicjalizację i przypisanie. Osoba::Osoba(char* i, char* n, int w) { imie = new char[strlen(i)+1]; strcpy(imie,i); nazwisko = new char[strlen(n)+1]; strcpy(nazwisko,n); wiek = w; } Osoba::~Osoba() { delete [] imie; delete [] nazwisko; }

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 4/21 Pole statyczne klasy Statyczna składowa klasy ma specjalną właściwość polegająca na tym, że program tworzy tylko jedną jej kopię, niezależnie od tego, ile obiektów danej klasy zostanie utworzonych. Innymi słowy pole statyczne klasy jest współdzielone przez wszystkie obiekty klasy. class Osoba { private: static int ileOsob; char* imie; char* nazwisko; int wiek; public: Osoba(); Osoba(char* i, char* n, int w); ~Osoba(); }; int Osoba::ileOsob = 0; Osoba::Osoba() { imie = new char[1]; imie[1]=\0; nazwisko = new char[1]; nazwisko[1]=0; ileOsob++; } Osoba::Osoba(char* i, char* n, int w) { imie = new char[strlen(i)+1]; strcpy(imie,i); nazwisko = new char[strlen(n)+1]; strcpy(nazwisko,n); wiek = w; ileOsob++; } Osoba::~Osoba() { ileOsob--; delete [] imie; delete [] nazwisko; } Pole statyczne inicjalizowane jest niezależnie poza deklaracją klasy i poza konstruktorami. Możliwe jest natomiast zainicjalizowanie stałego pola statycznego w deklaracji klasy.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 5/21 Pole statyczne klasy Statyczna składowa klasy ma specjalną właściwość polegająca na tym, że program tworzy tylko jedną jej kopię, niezależnie od tego, ile obiektów danej klasy zostanie utworzonych. Innymi słowy pole statyczne klasy jest współdzielone przez wszystkie obiekty klasy. class Osoba { private: static int ileOsob; char* imie; char* nazwisko; int wiek; public: Osoba(); Osoba(char* i, char* n, int w); ~Osoba(); }; int Osoba::ileOsob = 0; Osoba::Osoba() { imie = new char[1]; imie[1]=\0; nazwisko = new char[1]; nazwisko[1]=0; ileOsob++; } Osoba::Osoba(char* i, char* n, int w) { imie = new char[strlen(i)+1]; strcpy(imie,i); nazwisko = new char[strlen(n)+1]; strcpy(nazwisko,n); wiek = w; ileOsob++; } Osoba::~Osoba() { ileOsob--; delete [] imie; delete [] nazwisko; } Pole statyczne inicjalizowane jest niezależnie poza deklaracją klasy i poza konstruktorami. Możliwe jest natomiast zainicjalizowanie stałego pola statycznego w deklaracji klasy.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 6/21 char * Pola składowe imie oraz nazwisko w konstruktorze klasy Osoba są wskaźnikami, a zatem konstruktor musi zaalokować pamięć odpowiednią dla danego łańcucha znaków przekazanego jako argument do konstruktora. Osoba::Osoba(char* i, char* n, int w) { imie = new char[strlen(i)+1]; strcpy(imie,i); nazwisko = new char[strlen(n)+1]; strcpy(nazwisko,n); wiek = w; ileOsob++; } Przy czym wskaźnik do łańcucha można przekazać do konstruktora podczas inicjalizacji obiektu: Osoba o(Jan,Kowalski,37); strlen(char*) Funkcja zwraca długość łańcucha (nie uwzględnia końcowego znaku null) strcpy(cel, źródło) Funkcja kopiująca łańcuch znaków. Należy pamiętać, że instrukcja: nazwisko = n spowoduje tylko skopiowanie adresu.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 7/21 Konstruktor kopiujący Podczas inicjalizacji jednego obiektu drugim, kompilator automatycznie generuje konstruktor zwany konstruktorem kopiującym. Zadaniem tego konstruktora jest kopiowanie obiektu istniejącego do obiektu nowo tworzonego. Konstruktor ten jest używany podczas inicjalizacji, a nie podczas przypisania. Prototyp konstruktora kopiującego: NazwaKlasy(const NazwaKlasy &); Osoba o1(Jan, Dzik, 47); Osoba o2 = o1; //działa konstruktor kopiujący Osoba o3; o3 = o1; // nie jest używany konstruktor kopiujący

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 8/21 Kiedy działa konstruktor kopiujący? Konstruktor kopiujący zostaje wywołany wówczas, gdy nowo tworzony obiekt jest inicjalizowany istniejącym obiektem tej samej klasy. Osoba o1(Jan, Dzik, 47); Osoba o2 = o1; Kompilator używa konstruktora kopiującego, gdy program generuje kopię obiektu (np. w sytuacji, gdy obiekt przekazywany jest do funkcji przez wartość). void f(Osoba o); //funkcja, do której przekazywany jest obiekt przez wartość. Osoba o1(Alicja, Lis, 32); f(o1); Niektóre kompilatory używają konstruktora kopiującego, gdy funkcja zwraca obiekt. Osoba g() { return Osoba(Jan,Kowalski,23); }

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 9/21 Co robi konstruktor kopiujący? Domyślny konstruktor kopiujący wykonuje tzw. kopiowanie płytkie, tzn. kopiuje tylko do nowotworzonego obiektu wartość każdej niestatycznej składowej kopiowanego obiektu. (Statyczne składowe nie są kopiowane, gdyż należą one do całej klasy, a nie pojedynczych obiektów). class A { private: static int i; int x; double y; bool z; public: A(int _x, double _y, bool _z) { x = _x; y = _y; z = _z; } }; int A::i = 0; int main() { A a(2,4,true); A b = a; //domyślny konstruktor kopiujący return 0; } a x = 2 y = 4 z = true b x = 2 y = 4 z = true i = 0 Obiekt b jest kopią obiektu a. Zmienna statyczna i nie jest kopiowana.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 10/21 Przykład użycia jawnego konstruktora kopiującego Jeśli klasa zawiera pole statyczne, którego wartość jest zmieniana przez konstruktor (np. zliczanie utworzonych obiektów), wówczas należy zdefiniować w sposób jawny konstruktor kopiujący, który będzie aktualizował pole statyczne. class A { private: static int i; int x; double y; bool z; public: A(int _x, double _y, bool _z) { x = _x; y = _y; z = _z; i++; } ~A(){i--;} A(const A & a) //konstruktor //kopiujący { i++; x = a.x; y = a.y; z = a.z; } }; int A::i = 0; int main() { A a(2,4,true); A b = a; //działą jawny konstruktor kopiujący return 0; }

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 11/21 Domyślny konstruktor kopiujący a łańcuchy znaków class B { private: char* tekst; int x; public: B(char* t, int _x) { tekst = new char[strlen(t)+1]; strcpy(tekst,t); x = _x; } ~B() { delete [] tekst; } }; int main() { B b1(Ala ma kota,10); B b2 = b1; return 0; } b1 tekst = 0xbf x = 10 Ala ma kota Obiekt b2 jest kopią obiektu b1. Adres 0xbf b2 tekst = 0xbf x = 10 Jeżeli pole składowe klasy jest wskaźnikiem do łańcucha znaków, wówczas domyślny konstruktor kopiujący kopiuje jedynie adresy, a nie cały łańcuch znaków.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 12/21 Domyślny konstruktor kopiujący a łańcuchy znaków c.d. class B { private: char* tekst; int x; public: B(char* t, int _x) { tekst = new char[strlen(t)+1]; strcpy(tekst,t); x = _x; } ~B() { delete [] tekst; } wypisz() { cout << tekst << << x << endl; } }; void f(B b) // obiekt przekazywany przez wartość { b.wypisz(); } int main() { B b1(Ala ma kota,10); f(b1); b1.wypisz(); return 0; } Działanie programu: Ala ma kota (ewentualnie wystąpi błąd)

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 13/21 Rozwiązanie problemu class B { private: char* tekst; int x; public: B(char* t, int _x) { tekst = new char[strlen(t)+1]; strcpy(tekst,t); x = _x; } B(const B & a) { x = a.x; tekst = new char[strlen(a.tekst)+1]; strcpy(tekst,a.tekst); } ~B() { delete [] tekst; } }; Jeśli klasa posiada składowe, które są wskaźnikami inicjalizowanymi za pomocą operatora new, wówczas należy napisać jawny konstruktor kopiujący, który skopiuje całe dane wskazywane przez wskaźniki. Jest to tzw. głębokie kopiowanie.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 14/21 Rozwiązanie problemu c.d. void f(B b) { b.wypisz(); } int main() { B b1(Ala ma kota,10); f(b1); b1.wypisz(); return 0; } b1 tekst = 0xbf x = 10 Ala ma kota Adres 0xbf b tekst = 0xbf x = 10 Argument rzeczywisty Argument formalny (parametr) Ala ma kota Adres 0xbf858098

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 15/21 Problemy z operatorem = Analogiczne problemy, które pojawiają się podczas kopiowania obiektu, mogą się pojawić podczas przypisania jednego obiektu drugim. Operacja przypisania wykonywana jest poprzez operator przypisania (=), który podobnie jak konstruktor kopiujący może być przeciążony przez programistę. Prototyp operatora przypisania: NazwaKlasy & NazwaKlasy::operator=(const NazwaKlasy &); Operator = używany jest wówczas, gdy do utworzonego obiektu przypisujemy drugi, jak w przykładzie poniżej: Osoba o1(Jan, Kowalski, 45); Obiekt o2 = o1; //działa konstruktor kopiujący Osoba o3; o3 = o1; //działa operator przypisania Inicjalizacja obiektu obiektem istniejącym zawsze powoduje wywołanie konstruktora kopiującego, ponadto w niektórych kompilatorach użycie operatora = powoduje wywołanie funkcji operator=.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 16/21 Działanie operatora = Operator przypisania w postaci niejawnej (nieprzeciążonej przez użytkownika) podobnie jak domyślny konstruktor kopiujący kopiuje pola składowe obiektu (poza statycznymi). Jest to również tzw. płytkie kopiowanie, czego konsekwencją będzie wskazywanie tego samego łańcucha znaków poprzez wskaźnik w oryginalnym obiekcie jak i jego kopii. class Osoba { private: char* imie; char* nazwisko; int wiek; public: Osoba() {}; Osoba(char* i, char* n, int w); ~Osoba(); }; Osoba::Osoba(char* i, char* n, int w) { imie = new char[strlen(i)+1]; strcpy(imie,i); nazwisko = new char[strlen(n)+1]; strcpy(nazwisko,n); wiek = w; ileOsob++; } Osoba::~Osoba() { ileOsob--; delete [] imie; delete [] nazwisko; } int main() { Osoba janek(Jan, Kowalski, 43); Osoba jan; jan = janek; return 0; }

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 17/21 Działanie domyślnego operatora = Po wywołaniu destruktora obiektu janek janek imie = 0xbf nazwisko = 0xbf wiek = 43 Jan Adres 0xbf jan imie = 0xbf nazwisko = 0xbf wiek = 43 Kowalski Adres 0xbf jan imie = 0xbf nazwisko = 0xbf wiek = 43

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 18/21 Przeciążanie operatora = Aby uniknąć problemów związanych z operatorem przypisania, należy jawnie zdefiniować funkcję przeciążającą operator =, która wykona tzw. głęboką kopię. Mechanizm działania przeciążonego operatora = jest podobny do konstruktora kopiującego, przy czym należy pamiętać o następujących istotnych uwagach: 1.Obiekt do którego będzie przypisywany drugi może odnosić się do danych, które zostały zaalokowane operatorem new, zatem operator = powinien zwolnić pamięć. 2.W związku z punktem powyższym, nowa funkcja = nie powinna pozwolić na przypisanie do obiektu jego samego. 3.Przeciążony operator = powinien zwracać referencję do obiektu, dzięki czemu możliwe będzie łączenie operatorów =.

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 19/21 Przeciążony operator = Osoba & Osoba::operator=(const Osoba & o) //uwaga 3 (funkcja zwraca referencję) { if (this == &o) return *this;//uwaga 2 (brak możliwości przypisania obiektu do samego siebie) delete [] imie; delete [] nazwisko;//uwaga 1 (zwolnienie niepotrzebnej pamięci) imie = new char[strlen(o.imie)+1]; strcpy(imie, o.imie); nazwisko = new char[strlen(o.nazwisko)+1]; strcpy(nazwisko, o.nazwisko); return *this; }

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 20/21 Metoda statyczna class C { private: static int licz; int y; public: C(int _y); ~C(); static int ile(); }; int C::ile = 0; C::C(int _y) { y = _y; licz++; } C::~C() { licz--; } int C::ile() { return licz; } Słowo kluczowe static występuje tylko w deklaracji, nie w definicji. Metoda statyczna nie może być wywołana przez obiekt (C++). Do metody statycznej odwołujemy się poprzez nazwę klasy i operator zasięgu :: Metoda statyczna może korzystać wyłącznie z pól statycznych klasy. int main() { C c(2); C c(10); cout << Ilość utworzonych obiektów: << C::ile(); return 0; }

Programowanie obiektowe Wykład 3 dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ. 21/21 Dziękuję za uwagę