LEKCJA 23 - Co nowego w C++? ________________________________________________________________ Z tej lekcji dowiesz si�, jakie mechanizmy C++ pozwalaj� na stosowanie nowoczesnego obiektowego i zdarzeniowego stylu programowania i co programy robi� z pami�ci�. ________________________________________________________________ W por�wnaniu z klasycznym C - C++ posiada: * rozszerzony zestaw s��w kluczowych (ang. keywords): ** nowe s�owa kluczowe C++: class - klasa, delete - skasuj (dynamicznie utworzony obiekt), friend - "zaprzyja�nione" funkcje z dost�pem do danych, inline - wpleciony (funkcje przeniesione w formie rozwini�tej do programu wynikowego), new - utw�rz nowy obiekt, operator - przyporz�dkuj operatorowi nowe dzia�anie, private - dane i funkcje prywatne klasy (obiektu), do kt�rych zewn�trzne funkcje nie maj� prawa dost�pu, protected - dane i funkcje "chronione", dost�pne z ograniczeniami, public - dane i funklcje publiczne, dost�pne bez ogranicze�, template - szablon, this - ten, pointer wskazuj�cy bie��cy obiekt, virtual - funkcja wirtualna, abstrakcyjna, o zmiennym dzia�aniu. * nowe operatory (kilka przyk�ad�w ju� widzieli�my), np.: << - wy�lij do strumienia wyj�ciowego, >> - pobierz ze strumienia wej�ciowego. * nowe typy danych: klasy, obiekty, abstrakcyjne typy danych (ang. ADT). * nowe zasady pos�ugiwania si� funkcjami: funkcje o zmiennej liczbie argument�w, funkcje "rozwijane" inline, funkcje wirtualne, itp.; Przede wszystkim (i od tego w�a�nie rozpoczniemy) zobaczymy funkcje o nowych mo�liwo�ciach. ROZSZERZENIE C - FUNKCJE. Funkcje uzyskuj� w C++ znacznie wi�cej mo�liwo�ci. Przegl�d rozpoczniemy od sytuacji cz�sto wyst�puj�cej w praktyce programowania - wykorzystywania domy�lnych (ang. default) parametr�w. FUNKCJE Z DOMY�LNYMI ARGUMENTAMI. Prototyp funkcji w C++ pozwala na podanie deklaracji domy�lnych warto�ci argument�w funkcji. Je�li w momencie wywo�ania funkcji w programie jeden (lub wi�cej) argument (�w) zostanie pomini�te, kompilator wstawi w puste miejsce domy�ln� warto�� argumentu. Aby uzyska� taki efekt, prototyp funkcji powinien zosta� zadeklarowany w programie np. tak: void Funkcja(int = 7, float = 1.234); Efekt takiego dzia�ania b�dzie nast�puj�cy: Wywo�anie w programie: Efekt: ________________________________________________________________ Funkcja(99, 5.127); Normalnie: Funkcja(99, 5.127); Funkcja(99); Funkcja(99, 1.234); Funkcja(); Funkcja(7, 1.234); ________________________________________________________________ [!!!] Argument�w mo�e ubywa� wy��cznie kolejno. Sytuacja: Funkcja(5.127); //�LE Funkcja(99); //DOBRZE jest w C++ niedopuszczalna. Kompilator potraktuje liczb� 5.127 jako pierwszy argument typu int i wyst�pi konflikt. [P079.CPP] #include <iostream.h> void fun_show(int = 1234, float = 222.00, long = 333L); main() { fun_show(); // Trzy arg. domyslne fun_show(1); // Pierwszy parametr fun_show(11, 2.2); // Dwa parametry fun_show(111, 2.22, 3L); // Trzy parametry return 0; } void fun_show(int X, float Y, long Z) { cout << "\nX = " << X; cout << ", Y = " << Y; cout << ", Z = " << Z; } Uruchom program i przekonaj si�, czy wstawianie argument�w domy�lnych przebiega poprawnie. W KT�RYM MIEJSCU UMIESZCZA� DEKLARACJE ZMIENNYCH. C++ pozwala deklarowa� zmienne w dowolnym miejscu, z zastrze�eniem, �e deklaracja zmiennej musi nast�pi� przed jej u�yciem. Umieszczanie deklaracji zmiennych mo�liwie blisko miejsca ich u�ycia znacznie poprawia czytelno�� (szczeg�lnie du�ych "wieloekranowych") program�w. Klasyczny spos�b deklaracji zmiennych: int x, y, z; ... main() { ... z = x + y + 1; ... } mo�e zosta� zast�piony deklaracj� w miejscu zastosowania (w tym np. wewn�trz p�tli): main() { ... for ( int i = 1; i <= 10; i++) cout << "Biezace i wynosi: " << i; ... } Nale�y jednak pami�ta� o pewnym ograniczeniu. Zmienne deklarowane poza funkcj� main() s� traktowane jako zmienne globalne i s� widoczne (dost�pne) dla wszystkich innych element�w programu. Zmienne deklarowane wewn�trz bloku/funkcji s� zmiennymi lokalnymi i mog� "przes�ania�" zmienne globalne. Je�li wielu zmiennym nadamy te same nazwy-identyfikatory, mo�emy prze�ledzi� mechanim przes�aniania zmiennych w C++. W przyk�adzie poni�ej zastosowano trzy zmienne o tej samej nazwie "x": [P080.CPP] //Program demonstruje przes�anianie zmiennych #include <iostream.h> int x = 1; //Zmienna globalna void daj_x(void); //Prototyp funkcji main() { int x = 22; //Zmienna lokalna funkcji main cout << ::x << " <-- To jest globalny ::x \n"; cout << x << " <-- A to lokalny x \n"; daj_x(); return 0; } void daj_x(void) { cout << "To ja funkcja daj_x(): \n"; cout << ::x << " <-- To jest globalny ::x \n"; cout << x << " <-- A to lokalny x \n"; int x = 333; cout << "A to moja zmienna lokalna - automatyczna ! \n"; cout << x << " <-- tez x "; } Program wydrukuje tekst: 1 <-- To jest globalny ::x 22 <-- A to lokalny x To ja funkcja daj_x(): 1 <-- To jest globalny ::x 1 <-- A to lokalny x A to moja zmienna lokalna - automatyczna ! 333 <-- tez x Zwr�� uwag�, �e zmienne deklarowane wewn�trz funkcji (tu: main()) nie s� widoczne dla innych funkcji (tu: daj_x()). Operator :: (ang. scope) pozwala nam wybiera� pomi�dzy zmiennymi globalnymi a lokalnymi. TYP WYLICZENIOWY enum JAKO ODR�BNY TYP ZMIENNYCH. W C++ od momentu zdefiniowania typu wyliczeniowego enum staje si� on r�wnoprawnym ze wszystkimi innymi typem danych. Program poni�ej demonstruje przyk�ad wykorzystania typu enum w C++. [P081.CPP] # include <iostream.h> enum ciuchy { niewymowne = 1, skarpetka, trampek, koszula, marynarka, czapa, peruka, koniec }; main() { ciuchy n; do { cout << "\nNumer ciucha ? --> (1-7, 8 = quit): "; cin >> (int) n; switch (n) { case niewymowne: cout << "niewymowne"; break; case skarpetka: cout << "skarpetka"; break; case trampek: cout << "trampek"; break; case koszula: cout << "koszula"; break; case marynarka: cout << "marynarka"; break; case czapa: cout << "czapa"; break; case peruka: cout << "peruka"; break; case koniec: break; default: cout << "??? Tego chyba nie nosze..."; } } while (n != koniec); return 0; } Zwr�� uwag� w programie na forsowanie typu (int) przy pobraniu odpowiedzi-wyboru z klawiatury. Poniewa� w C++ "ciuchy" stanowi� nowy (zdefiniowany przed chwil�) typ danych, do uto�samienia ich z typem int niezb�dne jest wydanie takiego polecenia przy pobieraniu danych ze strumienia cin >> . W opcjach pracy kompilatora mo�esz w��czy�/wy��czy� opcj� "Treat enums as int" (traktuj typ enum jak int) i wtedy pomin�� forsowanie typu w programie. JEDNOCZESNE ZASTOSOWANIE DWU KOMPILATOR�W. Jak ju� wspomnieli�my wcze�niej kompilator C++ sk�ada si� w istocie z dwu r�nych kompilator�w: * kompilatora C wywo�ywanego standardowo dla plik�w *.C, * kompilatora C++ wywo�ywanego standardowo dla plik�w *.CPP. Oba kompilatory stosuj� RӯNE metody tworzenia nazw zewn�trznych (ang. external names). Je�li zatem program zawiera modu�, w kt�rym funkcje zosta�y przekompilowane w trybie charakterystycznym dla klasycznego C - C++ powinien zosta� o tym poinformowany. Dla przyk�adu, C++ * kategorycznie kontroluje zgodno�� typ�w argument�w, * na sw�j w�asny u�ytek dodaje do nazw funkcji przyrostki (ang. suffix) pozwalaj�ce na okre�lenie typu parametr�w, * pozwala na tworzenie tzw. funkcji polimorficznych (kilka r�nych funkcji o tej samej nazwie), itp. Zwyk�y C tego nie potrafi i nie robi. Dlatego te� do wprowadzenia takiego podzia�u kompetencji nale�y czasem zastosowa� deklaracj� extern "C". Funkcja rand() w programie poni�ej generuje liczb� losow�. [P081.CPP] #include <iostream.h> extern "C" { # include <stdlib.h> //Prototyp rand() w STDLIB.H } main() { cout << rand(); return 0; } GENERACJA LICZB LOSOWYCH. Kompilatory C++ umo�liwoaj� generacj� liczb pseudolosowych u�ytecznych cz�sto w obliczeniach statystycznych (np. metoda Monte Carlo) i emulacji "rozmytaj" arytmetyki i logiki (ang.fuzzy math). [!!!] UWAGA - Liczby PSEUDO-Losowe. ________________________________________________________________ Funkcja rand() powoduje uruchomienie generatora liczb pseudolosowych. Je�li chcesz uzyska� liczb� pseudolosow� z zadanego przedzia�u warto�ci, najlepiej zastosuj dzielenie modulo: int n = rand % 1...
lazarusp22