Programowanie obiektowe III rok EiT

Slides:



Advertisements
Podobne prezentacje
C++ wykład 9 ( ) Szablony.
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
Standardowa biblioteka języka C++
Klasy i obiekty.
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();
PROGRAMOWANIE STRUKTURALNE
Szablony (wzorce) Przykład 1: Szablon klasy -
Struktury.
Tablice.
C++ wykład 2 ( ) Klasy i obiekty.
Zasady zaliczenia Warunki uzyskania zaliczenia:
Języki programowania obiektowego
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
Programowanie obiektowe III rok EiT
Programowanie obiektowe III rok EiT
Podstawy informatyki 2013/2014
Informatyka I Wykład 10 WSKAŹNIKI I ADRESY Jerzy F. Kotowski.
T: Różnice pomiędzy programowaniem strukturalnym a obiektowym
Jerzy F. Kotowski1 Informatyka I Wykład 11 STRUKTURY I UNIE.
Podstawy programowania
Programowanie obiektowe w C++
Programowanie obiektowe III rok EiT dr inż. Jerzy Kotowski Wykład VIII.
Jerzy F. Kotowski1 Informatyka I Wykład 14 DEKLARATORY.
Programowanie obiektowe III rok EiT dr inż. Jerzy Kotowski Wykład XIII.
Programowanie obiektowe III rok EiT dr inż. Jerzy Kotowski Wykład IX.
Programowanie obiektowe III rok EiT
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 8 ( )
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 +
K URS JĘZYKA C++ – WYKŁAD 10 ( ) Szablony.
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 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 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 ( )
(według:
Programowanie Obiektowe – Wykład 2
Kurs języka C++ – wykład 4 ( )
Programowanie obiektowe – zastosowanie języka Java SE
Założenia projektowe Javy
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 III rok EiT 2017-03-28 09:38:18 Programowanie obiektowe III rok EiT dr inż. Jerzy Kotowski Wykład X

Klasówka Program wykładu Język C++ Przykład problemu Klasy, c.d. Wskaźnik this Klasy z konstruktorem i destruktorem Przykład problemu Podstawy języka JAVA Klasówka

Literatura C++ for C programmers, Ira Pohl, The Benjamin/Cummings Publishing Company, Inc. Symfonia C++, Jerzy Grębosz, Oficyna Kallimach, Kraków 1999

Wskaźnik this Słowo kluczowe this oznacza niejawnie deklarowany self-referential poiner. Jednym z obszarów wykorzystania this jest tworzenie konstrukorów i destruktorów zawierających wprowadzane przez programistę funkcje do alokacji pamięci Używanie wskaźnika this może spowodować wzrost efektywności programu Przykład użycia: sztuka dla sztuki  class X { char c; public: void init(char b) {c=b;} char valc() {return(this->c);} char val() {return c;} }; Wygoda: return *this; Typ wskaźnika: X const * To znaczy: this pokazuje na obiekty klasy X ale nie wolno nim poruszać. Jest to stały wskaźnik.

Konstruktory i destruktory - start Aby klasa, czyli typ użytkownika przypominała typy wbudowane (J. Grębosz) wymyślono: Konstruktor i destruktor, Funkcje składowe przeładowujące operatory, Operatory konwersji. Konstruktor jest to member function, której nazwa jest identyczna z nazwa klasy. Tworzy on obiekty swojej klasy. Ten proces może uruchamiać procedury inicjalizacji data members i alokacji pamięci z wykorzystaniem operatora new. Destruktor jest to member function, której nazwa jest identyczna z nazwą klasy z poprzedzającym ją znakiem tilde (~). Zwykle jego funkcja polega na zniszczeniu obiektu swojej klasy, najczęściej poprzez wykorzystanie operatora delete. Konstruktor może być przeciążany a destruktor nie. Konstruktor i destruktor nie mogą nic zwracać. Nawet nie mogą zwracać void. Konstruktory i destruktory mogą zawierać słowo return ale tylko w składni return;

Własności konstruktora Konstruktor może być wywoływany do tworzenia obiektów typu const i volatile ale sam nie może być funkcją takiego typu. Konstruktor nie może być typu static. Konstruktor nie może być typu virtual. Nie można posłużyć się adresem konstruktora. Zmienna typu klasa z konstruktorem nie może członkiem unii. Zgoda może bowiem doprowadzić do walki pomiędzy konstruktorami. Konstruktor domniemany to taki, który można wywołać bez żadnego argumentu. Konstruktor domniemany jest tylko jeden. Konstruktor ze wszystkimi argumentami domniemanymi jest konstruktorem domniemanym. Konstruktor domniemany pozwala na array declaration. Jeżeli klasa nie ma żadnego konstruktora to wtedy kompilator sam generuje automatyczny konstruktor domniemany. class Complex{ float Re,Im; public: Complex(float x=0, float y=0) { Re=x; Im=y;} }a,b(-1),c(0,1),z[10];

Lista inicjalizacyjna konstruktora Lista inicjalizacyjna może pojawić się w definicji konstruktora. Deklaracja pozostaje niezmieniona. Lista inicjalizacyjna specyfikuje jak zainicjować niestatyczne składniki klasy. Przykład: było Complex(float x=0, float y=0) { Re=x; Im=y;} może być Complex(float x=0, float y=0): Re(x), Im(y){} Elementy składni: dwukropek i przecinek. W przykładzie mamy do czynienia z definicją inline konstruktora wewnątrz klasy. Lista inicjalizacyjna przydaje się przy przekazywaniu argumentów klasom bazowym przy dziedziczeniu

Konstruktor kopiujący .. \test0.sln Konstruktor typu type::type(type& x) nosi nazwę konstruktora kopiującego. Gwarancja nietykalności wzorca: type::type(const type& x) Konstruktor kopiujący może być wywołany w sposób jawny: type obiekt_nowy = type(obiekt_wzór); Konstruktor kopiujący jest wykorzystywany do kopiowania wartości typu type do innej jeżeli: zmienna typu type jest inicjalizowana przez wartość typu type wartość typu type jest przekazywana jako argument funkcji wartość typu type jest zwracana przez funkcję. Jeżeli w klasie nie ma konstruktora kopiującego to wtedy, gdy zajdzie jedna z sytuacji przedstawionych powyżej, kompilator generuje automatyczny konstruktor kopiujący. Kopiuje on zgodnie z zasadą „składowa po składowej”. Może to być przyczyną niejednej tragedii. konstruktor kopia.cpp

Przykład – nowa wersja klasy stack const int max_len=1000; enum Boolean {False,True}; class stack { char s[max_len]; int top; public: void reset() { top = 0; } // definition void push(char c); // function prototype char pop() { return (s[top--]);} char pop(int n); // overloading, prototype char top_of() { return (s[top]); } Boolean empty() { return ((Boolean)(top == 0)); } Boolean empty(int n); // overloading, prototype Boolean full() { return ((Boolean)(top == max_len - 1 )); } }; enum Boolean {false,true}; class stack { char *s; int max_len; int top; public: stack(void) { s=new char[1000]; max_len=1000; top=0; } stack(int size) {s=new char[size]; max_len=size; top=0; } stack(int size, char *str); ~stack(void) { delete s; } void reset() { top = 0; } void push(char c); char pop() { return (s[top--]); } char pop(int n); char top_of() { return (s[top]); } Boolean empty() { return ((Boolean)(top == 0)); } Boolean empty(int n); Boolean full() {return((Boolean)(top == max_len - 1 )); } };

Nowa wersja klasy stack - różnice Nie ma deklaracji const int max_len=1000; Zamiast tego jest nowy data member int max_len; Nie ma pola char s[max_len]; Zamiast tego jest char *s; Klasa stack ma trzy konstruktory: pierwszy bez argumentów - jego działanie jest równoważne działaniu niejawnego konstruktora, drugi zakłada stos o rozmiarze określonym przez jego parametr, trzeci ma dwa argumenty - zakłada stos o rozmiarze określonym przez pierwszy i kopiuje na stos łańcuch przekazywany przez drugi argument bez znaku końca łańcucha - top jest ustawiony na ostatni element łańcucha. Klasa stack ma destruktor. Interfejsy w obu wersjach pozostały identyczne

Klasa String z dynamiczną alokacją pamięci .. \test0.sln const int max_len=255; class String { char s[max_len]; // dwa skladniki typu private int len; static Stan; // składowa statyczna public: // cztery skladniki typu public void assign(char *st); int lenght() { return(len); } void print(); static void switch_stan(void); }; class String{ char *s; int len; static Stan; public: String(void); String(int n); String(char *p); String(String& str); ~String() { delete s; } int lenght() { return(len); } void assign(char *str); void print(); static void switch_stan(void); }; String dynamiczny.cpp Różnice: Nie ma pola const int max_len=255; Nie ma pola char s[max_len]; jest pole char *s; Pojawiły się cztery konstruktory.

Klasa String z dynamiczną alokacją pamięci – definicje konstruktorów String::String(void) { s=new char[81]; s[0]=0; // przerwanie łańcucha len=80; cout << "\nPracuje konstruktor domniemany:\n"; print(); } String::String(int n) { s=new char[n+1]; s[0]=0; // przerwanie łańcucha len=n; cout << "\nPracuje konstruktor z jednym argumentem:\n"; print(); } String::String(char *p) // WAŻNE { len=(int)strlen(p); // rzutowanie s=new char[len+1]; strcpy(s,p); cout << "\nPracuje operator konwersji:\n"; print(); } String::String(String& str) { len=str.len; s=new char[len+1]; strcpy(s,str.s); cout << "\nPracuje konstruktor kopiujacy:\n"; print(); }

Klasa vect z dynamiczną alokacją pamięci i kontrolą indeksu. \test0 Klasa vect z dynamiczną alokacją pamięci i kontrolą indeksu .. \test0.sln Program ilustruje sposób wykorzystania ADT do stworzenia tablicy elementów (jako klasy), w której będzie można kontrolować wykraczanie indeksów poza dopuszczalny przedział wartości. class vect { int *p; int size; public: int ub; // upper bound = size-1 vect() { size=10; p=new int[size]; ub=size-1; } vect(int n); // konstruktor z argumentem ~vect() { delete p; } int& element (int i); }; int& vect::element(int i) { if(i<0||i>ub) { cerr << "Illegal vector indeks " << i << "\n"; exit(1);} return(p[i]); } // vect.cpp

Klasa vect z dynamiczną alokacją pamięci i kontrolą indeksu Dwa pola typu private: wskaźnik do pola roboczego int *p oraz jego rozmiar int size. W obszarze public jest data member int ub; Klasa ma dwa konstruktory: pierwszy bez argumentów deklarujący tablicę 10 elementową drugi z jednym argumentem int n zakładający tablicę n-elementową. Dostęp do elementów tablicy jest poprzez funkcję element. Najciekawszy element programu.Funkcja jest self indexing - sprawdza, czy indeks nie jest spoza zakresu. Funkcja zwraca referencję do i-tego elementu tablicy, to znaczy udostępnia ten element. Zwracana wartość jest zatem lvalue i może być wykorzystywana jako lewy operand operatora podstawiania. Jest to technika stosowana w C++ jako wygodny mechanizm przy działaniach na bardziej skomplikowanych typach obiektowych. Można napisać: vect vv(8), uu[5]; vv.element(2)=uu[3].element(8); Lepiej by było tak: vv[2]=uu[3][8]; to kiedyś będzie

Klasa multi_v Deklarujemy klasę multi_v do przechowywania wieku, wagi i wzrostu grupy osób. Klasa zawiera trzy obiekty typu vect jako swoje składowe. Klasa ma wyłącznie elementy typu public. Konstruktor klasy multi_v jest konstruktorem z parametrem. Konstruktor ten ma puste wnętrze nie licząc listy inicjalizacyjnej, na której są wywołania konstruktora obiektu typu vect. Konstruktor klasy vect jest wywoływany trzy razy z parametrem i i tworzy trzy obiekty a(i),b(i),c(i). W starszych kompilatorach kolejność zakładania obiektów była nieokreślona. W nowszych kompilatorach kolejność jest zgodna z listą inicjalizacyjną - od lewej do prawej. class multi_v { public: vect a,b,c; multi_v(int i):a(i),b(i),c(i) {} };

Klasa vect i multi_v – kod klienta W segmencie main zakładamy obiekt a_w_h typu multi_v. Składa się on z trzech 5-elementowych tablic obiektów typu vect. Zwraca uwagę sposób użycia pola ub Pętla for(int i=0;i<=a_w_h.a.ub;i++) chodzi 5 razy. Na koniec wykonywane są destruktory w kolejności odwrotnej do wywołań konstruktorów. Są to destruktory elementów klasy vect. multi_v a_w_h(5); // age, weight and height for(int i=0;i<=a_w_h.a.ub;i++) { a_w_h.a.element(i)=21+i; a_w_h.b.element(i)=135+i; a_w_h.c.element(i)=62+i; } for(i=0;i<=a_w_h.a.ub;i++){ cout << a_w_h.a.element(i) << " years "; cout << a_w_h.b.element(i) << " pounds "; cout << a_w_h.c.element(i) << " inches\n";

Klasa matrix – uogólnienie klasy vect Przykład jest uogólnieniem tablicy jednowymiarowej. Istotnym novum jest postać konstruktora i destruktora. class matrix { int **p; int s1,s2; public: int ub1,ub2; matrix(int d1,int d2); ~matrix(); int& element(int i,int j); }; matrix::matrix(int d1,int d2) { s1=d1; s2=d2; p=new int* [s1]; for(int i=0; i<s1;i++) p[i]=new int[s2]; ub1=s1-1; ub2=s2-1; } matrix::~matrix() for(int i=0;i<s1;i++) delete p[i]; delete p; Konstruktor zakłada wpierw s1 elementową tablicę wskaźników do wierszy. Destruktor dealokuje pamięć w odwrotnej kolejności.

Klasa matrix – funkcja element i kod klienta .. \test0.sln int& matrix::element(int i,int j) { return (p[i][j]); } Kod klienta jest izomorficzny do kodu z programu tablica1.cpp tablica2.cpp int sz1,sz2; cout << "\nEnter two sizes: "; cin >> sz1 >> sz2; matrix A(sz1,sz2); // Istotna różnica cout << "\nEnter " << sz1 << " by " << sz2 << " ints:\n"; int i,j; for(i=0;i<sz1;i++) for(j=0;j<sz2;j++) cin >> A.element(i,j); …

Lista jednokierunkowa - a singly linked list Lista jednokierunkowa jest bardzo użytecznym obiektem ADT. Jest to prototyp wielu struktur danych, które noszą nazwę self-referential structures. Obiekty tego typu charakteryzują się w szczególności tym, że jako jedno ze swoich pól mają wskaźnik do danej tego samego typu. Idea listy jednokierunkowej: Elementy dodajemy na początku listy i pierwszy element listy jest jedynym, który można bezpośrednio z listy skasować. Każdy element listy zawiera wszystkie niezbędne informacje, wynikające ze specyfiki programu oraz adres następnego elementu na liście. W przykładzie element znajdujący się na liście jest skromnym obiektem typu char. struct listelem { // element listy char data; // informacje związane z elementem listelem *next; // adres do następnego elementu };

Klasa list Oba pola w strukturze listelem są typu public. Nie ma to specjalnie znaczenia ponieważ tajny jest adres do początku listy. Konstruktor inicjalizuje początek listy na NULL. Jest to klasyczne oznaczenie końca listy, lub faktu, że lista jest pusta. Destruktor wywołuje funkcję składową. Funkcja first zwraca adres do początku listy. Elementy listy są deklarowane jako struktury. Mamy zatem bezpośredni dostęp do ich pól. class list { listelem *h; // wskaźnik do początkowego elementu public: list() { h=0; } // konstruktor ~list() {release();}// destruktor void add(char c); // dodająca nowego element na początku void del(); // kasowanie elementu z początku listy listelem *first() { return h; }// adres do 1 elementu void pr_list(); // wyprowadzanie listy void release(); //zwalnianie pamięci };

Funkcje składowe klasy list void list::add(char c) // dodawanie elementu na początku listy { listelem *temp=new listelem; // przydzielanie pamięci temp->next=h; // dołączanie do listy temp->data=c; h=temp; // aktualizacja początku listy } // zarezerwowana pamięć nie jest zwalniana void list::pr_list() // wydruk całej listy listelem *temp=h; // adres do początku listy nie zmieni się while(temp!=0) // badanie końca listy cout << temp->data << " -> "; temp=temp->next; // przejście do następnego elementu } cout << "Koniec listy.\n";

Funkcje składowe klasy list - c.d. void list::del() // kasowanie jednego elementu z listy { listelem *temp=h; h=h->next; delete temp; // pamięć zajmowana przez pierwszy element } // na liscie wraca do stanu 'free store' void list::release() // kasowanie wszystkich elementów z listy while(h!=0) del(); } Funkcja release zdejmuje bieliznę ze sznurka zostawiając sznurek. Sznurek zdejmuje destruktor. Destruktor o treści delete h; zniszczy tylko pierwszy element na liście i popsuje listę bo nie będziemy w stanie znaleźć następnego elementu.

Klasa list - kod klienta .. \test0.sln list *p; // wskaźnik do listy { // początek wewnętrznego bloku list w; w.add('A'); w.add('B'); // dwa elementy na liście w.pr_list(); w.del(); // kasujemy pierwszy p=&w; p->pr_list(); // powinien byc identyczny wydruk } // niejawne wywołanie destruktora p->pr_list(); // lista została wyczyszczona lista jednokierunkowa.cpp Segment main zawiera inner block. Po wyjściu z niego uruchamiany jest destruktor i lista jest automatycznie kasowana. Przykładowy wydruk: B -> A -> Koniec listy. A -> Koniec listy. Koniec listy.