Upload
alika-dyer
View
13
Download
4
Embed Size (px)
DESCRIPTION
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: - PowerPoint PPT Presentation
Citation preview
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 funkcjamiskł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, 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 madostę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, w którym sięoblicza (do którego została wysłana przez kropkę).this wskaźnik do obiektu, w którym jesteśmyJeś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łazadeklarowana).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 wszystkodate (char * s); // robi konwersję z napisudate (int number); // number - zakodowana datadate (); // 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 automatyczniewykonywany w momencie powstania obiektu tej klasy (inicjalizacja).Destruktor jest automatycznie wykonywany w momencie ginięciaobiektu.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 formadate sylwester (“31 Grudnia 2003”);date kiedys; // bez inicjalizacjidate 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; } // destruktorvoid push (char c ) { *top++ = c; }char pop ( ) { return * --top; }
};
void f ( ){
char_stack s1 (100);......
} // po zakończeniu funkcji stos (tablica) zostanie zniszczony
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 nastatycznych 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ę();
}
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 przy przypisaniu b = a.
Konstruktor kopiujący jest wołany przy inicjacji zmiennejinnym obiektem lub przy przekazywaniu parametrów lubwynikó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 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
};
// ...
}