OOP C wstp klasy 1 Klasy Do struktury

  • Slides: 7
Download presentation
OOP C++ - wstêp, klasy 1 Klasy Do struktury można dołączyć operacje działające na

OOP C++ - wstêp, klasy 1 Klasy Do struktury można dołączyć operacje działające na jej polach. struct date { int day, month, year; void set (int d, int m, int y); int less (date d); void print ( ); }; Funkcje zadeklarowane w środku struktury nazywamy funkcjami składowymi (member functions). Wywołanie: date today, end_of_year; void f () { today. set (8, 12, 2003 ); today. print (); end_of_year. set (31, 12, 2003); end_of_year. print (); if (today. less(end_of_year)) {. . . } } Mechanizm wygodny, ale nieobiektowy. Klasy różnią się od struktur tylko ochroną atrybutów.

OOP C++ - wstêp, klasy 2 class date { public: void set (int d,

OOP C++ - wstêp, klasy 2 class date { public: void set (int d, int m, int y); int less(date d); void print ( ); private: int day, month, year; } Prywatna część klasy (w tym przypadku atrybuty obiektów klasy) może być używana wyłącznie przez funkcje składowe. Nie ma dostępu przez kropkę z zewnątrz do tych atrybutów. Publiczna część klasy stanowi interfejs obiektów klasy widoczny przez świat zewnętrzny. Definicje funkcji składowych (muszą gdzieś wystąpić): void date: : set (int d, int m, int y) { day = d; month = m; year = y; } int date: : less (date d) { // && ma wyższy priorytet niż || return ( year < d. year) || (year == d. year) && (month < d. month) || (year == d. year) && (month == d. month) && (day < d. day); } void date: : print () { cout << day << “ - “ << month << “ - “ << year; } void f () date today, end_of_year; { today. set (8, 12, 2003); . . . }

OOP C++ - wstêp, klasy 3 Każda funkcja składowa może odwołać się do obiektu,

OOP C++ - wstêp, klasy 3 Każda funkcja składowa może odwołać się do obiektu, w którym się oblicza (do którego została wysłana przez kropkę). this wskaźnik do obiektu, w którym jesteśmy Jeśli this użyty jest w obiekcie klasy date, to ma typ date * const. Tworzenie i usuwanie obiektu klasy Obiekt klasy może powstać: • w momencie powstania zmiennej typu tej klasy (przy jej deklaracji) • przez dynamiczne utworzenie go przez new date dzisiaj; // teraz powstaje obiekt klasy date *jutro; // tu nie ma jeszcze obiektu klasy date. . . jutro = new date; // dynamiczne powstanie obiektu klasy date Obiekt, który powstał automatycznie ginie, kiedy ginie zmienna, której był wartością (np. po zakończeniu funkcji, w której zmienna była zadeklarowana). Obiekt, który powstał na skutek wykonania new, ginie przez wykonanie na nim delete. Konstruktory / destruktory. class date { public: date (int d, int m, int y); // konstruktor inicjujący wszystko date (char * s); // robi konwersję z napisu date (int number); // number - zakodowana date (); // bez inicjalizacji ~date (); { } // destruktor - pusty. . . // funkcje set, less, print } date: : date(int d, int m, int y ) { day = d; month = m; year = y; }

OOP C++ - wstêp, klasy 4 Konstruktor obiektu (zdefiniowany w klasie) jest automatycznie wykonywany

OOP C++ - wstêp, klasy 4 Konstruktor obiektu (zdefiniowany w klasie) jest automatycznie wykonywany w momencie powstania obiektu tej klasy (inicjalizacja). Destruktor jest automatycznie wykonywany w momencie ginięcia obiektu. Na ogół konstruktory są przeciążone, tzn. mamy różne konstruktory, dla różnych sposobów inicjalizacji obiektu. date jutro = date ( 8, 12, 2003); date today (8, 12, 2003); // skrócona forma date sylwester (“ 31 Grudnia 2003”); date kiedys; // bez inicjalizacji date kto_to_wie (37963); // dzień o numerze 37963 // liczonym od 01 -01 -1900 date * koniec = new data (8, 12, 2003); W definicji klasy często stosujemy funkcje wstawiane (inline), jeżeli funkcje składowe są krótkie. Funkcja składowa jest wstawiana, jeżeli przy deklaracji podajemy od razu jej treść. Przykład zastosowania destruktora: class char_stack { private: int size; char *top; char *s; public: char_stack (int sz) ~char_stack ( ) void push (char c ) char pop ( ) }; { top = s = new char [size = sz]; } { delete[] s; } // destruktor { *top++ = c; } { return * --top; } void f ( ) { char_stack s 1 (100); . . . } // po zakończeniu funkcji stos (tablica) zostanie zniszczony

OOP C++ - wstêp, klasy 5 Statyczne składniki (atrybuty i funkcje) klas Statyczne zmienne

OOP C++ - wstêp, klasy 5 Statyczne składniki (atrybuty i funkcje) klas Statyczne zmienne będące składnikami klasy są odpowiednikami zmiennych klasowych - są atrybutami klasy, a nie obiektu (są współdzielone przez wszystkie obiekty danej klasy). Statyczne funkcje składowe są odpowiednikami metod klasowych. Są wykonywane w klasie, a nie w obiekcie. Mogą działać tylko na statycznych atrybutach klasy. class Rachunek { public: Rachunek ( int stan_początkowy = 0) // domyślny argument { stan = stan_początkowy; suma_rachunków += stan; } void wpłać ( int kwota ) { stan += kwota; suma_rachunków += kwota; } void wypłać (int kwota ) { stan -= kwota; suma_rachunków -= kwota; } static int daj_sumę ( ) { return suma_rachunków; } private: static int suma_rachunków; // suma stanu wszystkich rach. int stan; // stan tego rachunku }; int Rachunek: : suma_rachunków = 0; void f ( ) { Rachunek r 1(300), r 2, r 3(500); r 1. wpłać (400); . . cout << “Suma wszystkich” << Rachunek : : daj_sumę(); }

OOP C++ - wstêp, klasy 6 Konstruktor kopiujący class Napis { private: char *ptr;

OOP C++ - wstêp, klasy 6 Konstruktor kopiujący class Napis { private: char *ptr; int len; public: Napis () { ptr = NULL; len = 0; } Napis (char * str ) { len = strlen (str); ptr = new char [len +1]; strcpy (ptr, str); } ~ Napis () { delete[] ptr; } }; void fun ( ) { Napis a (“Test”); Napis b = a; // kopiowanie obiektu a na b. . . } Po zakończeniu funkcji fun zostanie 2 razy wykonany destruktor. Dwa razy zwolni się pamięć na string ptr - błąd! Ten sam problem powstaje przypisaniu b = a. Konstruktor kopiujący jest wołany przy inicjacji zmiennej innym obiektem lub przy przekazywaniu parametrów lub wyników. Domyślny konstruktor kopiujący - kopiuje obiekt składowa po składowej. Napis (const Napis & obj) { len = strlen (obj. ptr); ptr = new char [len + 1]; strcpy (ptr, obj. ptr); }

OOP C++ - wstêp, klasy 7 Zagnieżdżanie • Nie można zagnieżdżać funkcji • Można

OOP C++ - wstêp, klasy 7 Zagnieżdżanie • Nie można zagnieżdżać funkcji • Można zagnieżdżać klasy/struktury (w klasach i strukturach), ale z ograniczeniami: dostęp tylko do składowych statycznych (nazw typów, wyliczeń). • Można też deklarować klasy lokalne w funkcjach (są widoczne _tylko_ wewnątrz obejmującej funkcji, nie mogą więc mieć składowych statycznych) int f() { int k; void f 1(){} // Źle, nie wolno zagnieżdżać funkcji struct inner // OK, można definiować klasy/struktury lokalne { int i; void f 2(int); // Źle, musi być od razu definicja void f 3(){} // Ale to już OK void f 4(){return k; } // To też błąd }; //. . . }