LEKCJA 24 : SK�D WZIʣY SI� KLASY I OBIEKTY W C++. ________________________________________________________________ W trakcie tej lekcji dowiesz si�, sk�d w C++ bior� si� obiekty i jak z nich korzysta�. ________________________________________________________________ Zajmiemy si� teraz tym, z czego C++ jest najbardziej znany - zdolno�ci� pos�ugiwania si� obiektami. G��wn� zalet� programowania obiektowego jest wy�szy stopie� "modularyzacji" program�w. "Mudularyzacja" jest tu rozumiana jako mo�liwo�� podzia�u programu na niemal niezale�ne fragmenty, kt�re mog� opracowywa� r�ne osoby (grupy) i kt�re p�niej bez konflikt�w mo�na ��czy� w ca�o�� i uruchamia� natychmiast. C++ powsta�, gdy programy sta�y si� bardzo (zbyt) d�ugie. Mo�liwo�� skr�cenia program�w nie jest jednak�e jedyn� zalet� C++. W d�ugich, rozbudowanych programach trudno spami�ta� szczeg�y dotycz�ce wszystkich cz�ci programu. Je�li grupy danych i grupy funkcji uda si� po��czy� w modu�y, do kt�rych mo�na p�niej si�ga�, jak do pewnej odr�bnej ca�o�ci, znacznie u�atwia to �ycie programi�cie. Na tym, w pewnym uproszczeniu, polega idea programowania obiektowego. JAK STRUKTURY STAWA�Y SI� OBIEKTAMI. W C++ struktury uzyskuj� "troch� wi�cej praw" ni� w klasycznym C. Przyk�adowy program poni�ej demonstruje kilka sposob�w pos�ugiwania si� struktur� w C++. [P90.CPP] #include <iostream.h> struct Data { int dzien; int miesiac; int rok; }; Data NaszaStruktura = {3, 11, 1979}; //Inicjujemy strukture Data daty[16]; //Tablca struktur Data *p = daty; //Wskaznik do tablicy void Fdrukuj(Data); //Prototyp funkcji int i; //Licznik automat. 0 int main() { for (; i < 16; i++) { *(p + i) = NaszaStruktura; daty[i].rok += i; cout << "\nDnia "; Fdrukuj(daty[i]); cout << " Patrycja "; if ( !i ) cout << "urodzila sie, wiek - "; if (i > 0 && i < 14) cout << "miala "; if (i > 13) cout << "bedzie miec "; cout << i; if (i == 1) cout << " roczek"; else cout << " lat"; if (i > 1 && i < 5) cout << "ka"; cout << '.'; } return 0; } void Fdrukuj(Data Str) { char *mon[] = { "Stycznia","Lutego","Marca","Kwietnia","Maja","Czerwca", "Lipca","Sierpnia","Wrzesnia","Pazdziernika","Listopada", "Grudnia" }; cout << Str.dzien << ". " << mon[Str.miesiac-1] << ". " << Str.rok; } Pr�cz danych struktury w C++ mog� zawiera� tak�e funkcje. W przyk�adzie poni�ej struktura Data zawiera wewn�trz funkcj�, kt�ra przeznaczona jest do obs�ugi we w�a�ciwy spos�b danych wchodz�cych w sk�ad w�asnej struktury. [P091.CPP] #include <iostream.h> struct Data //Definicja struktury { int dzien, miesiac, rok; void Fdrukuj(); //Prototyp funkcji Data(); //Konstruktor struktury }; void Data::Fdrukuj() //Definicja funkcji { char *mon[] = { "Stycznia","Lutego","Marca","Kwietnia","Maja","Czerwca", "Lipca","Sierpnia","Wrzesnia","Pazdziernika","Listopada", "Grudnia" }; cout << dzien << ". " << mon[miesiac-1] << ". " << rok; } Data::Data(void) //Poczatkowa data - Konstruktor { dzien = 3; miesiac = 11; rok = 1979; } int main() { Data NStruktura; //Inicjujemy strukture cout << "\n Sprawdzamy: "; NStruktura.Fdrukuj(); //Wywolanie funkcji cout << " = "; cout << NStruktura.dzien << " . " << NStruktura.miesiac << " . " << NStruktura.rok; for (int i=0; i < 16; i++, NStruktura.rok++) { cout << "\nDnia "; NStruktura.Fdrukuj(); cout << " Patrycja "; if ( !i ) cout << "urodzila sie, wiek - "; if (i > 0 && i < 14) cout << "miala "; if (i > 13) cout << "bedzie miec "; cout << i; if (i == 1) cout << " roczek"; else cout << " lat"; if (i > 1 && i < 5) cout << "ka"; cout << '.'; } return 0; } Zwr�� uwag�, �e * odk�d dane sta�y si� elementem struktury, zacz�li�my odwo�ywa� si� do nich tak: nazwa_struktury.nazwa_pola; * gdy funkcje sta�y si� elementem struktury, zacz�li�my odwo�ywa� si� do nich tak: nazwa_struktury.nazwa_funkcji; Pojawi�y si� r�wnie� r�nice w sposobie definiowania funkcji: void Data::Fdrukuj() //Definicja funkcji { ... } oznacza, �e funkcja Fdrukuj() jest upowa�niona do operowania na wewn�trznych danych struktur typu Data i nie zwraca do programu �adnej warto�ci (void). Natomiast zapis: Data::Data(void) //Poczatkowa data - Konstruktor oznacza, �e funkcja Data(void) nie pobiera od programu �adnych parametr�w i tworzy (w pami�ci komputera) struktur� typu Data. Takie dziwne funkcje konstruuj�ce (inicjuj�ce) struktur� (o czym dok�adniej w dalszej cz�ci ksi��ki), nazywane w C++ konstruktorami nie zwracaj� do programu �adnej warto�ci. Zwr�� uwag�, �e konstruktory to specjalne funkcje, kt�re: -- maj� nazw� identyczn� z nazw� typu w�asnej struktury, -- nie posiadaj� wyspecyfikowanego typu warto�ci zwracanej do programu, -- s�u�� do zainicjowania w pami�ci p�l struktury, -- nie s� wywo�ywane w programie w spos�b jawny, lecz niejawnie, automatycznie. Podstawowym praktycznym efektem dodania do struktur funkcji sta�a si� mo�liwo�� skutecznej ochrony danych zawartych na polach struktury przed dost�pem funkcji z zewn�trz struktury. Przed dodaniem do struktury jej w�asnych wewn�trznych funkcji - wszystkie funkcje pochodzi�y z zewn�trz, wi�c "hermetyzacja" danych wewn�trz by�a niewykonalna. Zasady dost�pu okre�la si� w C++ przy pomocy s��w: public - publiczny, dost�pny, protected - chroniony, dost�pny z ograniczeniami, private - niedost�pny spoza struktury. Przyk�adowy program poni�ej demonstruje tzw. "hermetyzacj�" struktury (ang. encapsulation). W przyk�adzie poni�ej: * definiujemy struktur�; * definiujemy funkcje; * przekazujemy i pobieramy dane do/od struktury typu Zwierzak. Zmienna int schowek powinna sugerowa� ukryt� przez struktur� i niedost�pn� dla nieuprawnionych funkcji cz�� danych struktury a nie cechy anatomiczne zwierzaka. [STRUCT.CPP] # include "iostream.h" //UWAGA: schowek ma status private, jest niedostepny struct Zwierzak { private: int schowek; //DANE PRYWATNE - niedostepne public: void SCHOWAJ(int Xwe); //Funkcje dostepne zzewnatrz int ODDAJ(void); }; void Zwierzak::SCHOWAJ(int Xwe) //definicja funkcji { schowek = Xwe; } int Zwierzak::ODDAJ(void) { return (schowek); } main() { Zwierzak Ciapek, Azor, Kotek; // Struktury "Zwierzak" int Piggy; // zwykla zmienna Ciapek.SCHOWAJ(1); Azor.SCHOWAJ(22); Kotek.SCHOWAJ(-333); Piggy = -4444; cout << "Ciapek ma: " << Ciapek.ODDAJ() << "\n"; cout << "Azor ma: " << Azor.ODDAJ() << "\n"; cout << "Kotek ma: " << Kotek.ODDAJ() << "\n"; cout << "Panna Piggy ma: " << Piggy << "\n"; return 0; } // Proba nieautoryzowanego dostepu do danych prywatnych obiektu: // cout << Ciapek.schowek; // printf("%d", Ciapek.schowek); // nie powiedzie sie Powiedzie sie natomiast pr�ba dost�pu do "zwyk�ej" zmiennej - dowoln� metod� - np.: printf("%d", Piggy); //Prototyp ! # include <stdio.h> Je�li podejmiesz pr�b� odwo�ania si� do "zakapsu�kowanych" danych w zwyk�y spos�b - np.: cout << Ciapek.schowek; kompilator wy�wietli komunikat o b��dzie: Error: 'Zwierzak::schowek' is not accessible in function main() (pole schowek struktury typu Zwierzak (np. str. Ciapek) nie jest dost�pne z wn�trza funkcji main(). ) Do klas i obiekt�w ju� tylko male�ki kroczek. Jak przekonasz si� za chwil� - struktura Ciapek jest ju� w�a�ciwie obiektem, a typ danych Zwierzak jest ju� w�a�ciwie klas� obiekt�w. Wystarczy zamieni� s�owo "struct" na s�owo "class". [CLASS.CPP] # include "iostream.h" //w klasach schowek ma status private AUTOMATYCZNIE //slowo private stalo sie zbedne class Zwierzak { int schowek; public: void SCHOWAJ(int Xwe); //Funkcje dostepne zzewnatrz int ODDAJ(void); }; void Zwierzak::SCHOWAJ(int Xwe) { schowek = Xwe; } int Zwierzak::ODDAJ(void) { return (schowek); } main() { Zwierzak Ciapek, Azor, Kotek; // obiekty klasy "Zwierzak" int Piggy; // zwykla zmienna Ciapek.SCHOWAJ(1); Azor.SCHOWAJ(22); Kotek.SCHOWAJ(-333); Piggy = -4444; cout << "Ciapek ma: " << Ciapek.ODDAJ() << "\n"; cout << "Azor ma: " << Azor.ODDAJ() << "\n"; cout << "Kotek ma: " << Kotek.ODDAJ() << "\...
jacek_040