1 / 7

Klasy Do struktury można dołączyć operacje działające na jej polach. struct date {

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:

alika-dyer
Download Presentation

Klasy Do struktury można dołączyć operacje działające na jej polach. struct date {

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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.

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

  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 • 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 data • date (); // bez inicjalizacji • ~date (); { } // destruktor - pusty • ...... // funkcje set, less, print • } • date::date(int d, int m, int y ) • { • day = d; month = m; year = y; • }

  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) { top = s = new char [size = sz]; } • ~char_stack ( ) { delete[] s; } // destruktor • void push (char c ) { *top++ = c; } • char pop ( ) { return * --top; } • }; • void f ( ) • { • char_stack s1 (100); • ...... • } // po zakończeniu funkcji stos (tablica) zostanie zniszczony

  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 r1(300), r2, r3(500); • r1.wpłać (400); .... • cout << “Suma wszystkich” << Rachunek :: daj_sumę(); • }

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

  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 f1(){} // Źle, nie wolno zagnieżdżać funkcji struct inner // OK, można definiować klasy/struktury lokalne { int i; void f2(int); // Źle, musi być od razu definicja void f3(){} // Ale to już OK void f4(){return k;} // To też błąd }; // ... }

More Related