KLASY cz4. Dorota Pylak. destruktory składowe statyczne przeciążanie operatorów. wskaźniki

Podobne dokumenty
KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Do czego służą klasy?

KLASY cz.1. Dorota Pylak

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Do czego służą klasy?

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Wykład 8: klasy cz. 4

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006)

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Programowanie Obiektowo Zorientowane w języku C++ Klasy, pola, metody

Wstęp do Programowania 2

Wykład 5: Klasy cz. 3

TEMAT : KLASY DZIEDZICZENIE

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Programowanie obiektowe Wykład 3. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21

Wykład 4: Klasy i Metody

Przeciążenie operatorów

Rozdział 4 KLASY, OBIEKTY, METODY

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

ZASADY PROGRAMOWANIA KOMPUTERÓW

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Algorytmy i język C++

Wstęp do programowania

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Programowanie obiektowe i C++ dla matematyków

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Wstęp do informatyki- wykład 12 Funkcje (przekazywanie parametrów przez wartość i zmienną)

Pola i metody statyczne. Klasy zawierające pola i metody statyczne

Podstawy programowania skrót z wykładów:

PARADYGMATY PROGRAMOWANIA Wykład 2

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Zmienne, stałe i operatory

Programowanie obiektowe

Programowanie obiektowe w języku C++ dr inż. Jarosław Forenc

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

Zadania z podstaw programowania obiektowego

Szablony klas, zastosowanie szablonów w programach

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie Obiektowe i C++

Kurs WWW. Paweł Rajba.

Podstawy algorytmiki i programowania - wykład 4 C-struktury

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Struktury Struktura polami struct struct struct struct

2.4 Dziedziczenie. 2.4 Dziedziczenie Przykłady programowania w C - kurs podstawowy

C-struktury wykład. Dorota Pylak

Programowanie, część I

Podstawy Programowania Obiektowego

Język C++ wykład VI. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VI. dr Jarosław Mederski.

Język C++ zajęcia nr 2

Projektowanie klas c.d. Projektowanie klas przykład

Programowanie obiektowe w C++ Wykład 12

Definiowanie własnych klas

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Przeciążanie operatorów

Materiały do zajęć VII

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

Programowanie obiektowe

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Programowanie obiektowe i C++ dla matematyków

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

PARADYGMATY PROGRAMOWANIA Wykład 3

C-struktury wykład. Dorota Pylak

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE

Co to jest klasa? Z programistycznego punktu widzenia klasa stanowi typ danych, który odwzorowuje wspólne cechy jakiegoś obiektu.

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Wstęp do programowania

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

Laboratorium nr 12. Temat: Struktury, klasy. Zakres laboratorium:

Laboratorium 1 - Programowanie proceduralne i obiektowe

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

referencje Wykład 2. Programowanie (język C++) Referencje (1) int Num = 50; zdefiniowano zmienną Num (typu int) nadając jej wartość początkową 50.

Programowanie w języku C++

Dziedziczenie jednobazowe, poliformizm

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 5

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie Obiektowo Zorientowane w języku c++ Konstruktory

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

wykład V uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C++ klasy i obiekty wykład V dr Jarosław Mederski Spis Język C++ - klasy

Programowanie komputerowe. Zajęcia 7

Lab 9 Podstawy Programowania

Wstęp do programowania obiektowego. Wykład 2

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Podstawy informatyki. Elektrotechnika I rok. Język C++ Operacje na danych - wskaźniki Instrukcja do ćwiczenia

Programowanie obiektowe

Dziedziczenie. Ogólna postać dziedziczenia klas:

Transkrypt:

KLASY cz4. destruktory składowe statyczne przeciążanie operatorów Dorota Pylak wskaźniki

2 Klasy - podsumowanie poznanych wiadomości Deklaracja klasy może zawierać pola, konstruktory oraz metody. W deklaracji klasy znajdują się sekcje prywatne oraz publiczne. Zazwyczaj sekcja prywatna zawiera dane obiektu, a publiczna metody tworzące interfejs. Typowa deklaracja klasy ma postać: class NazwaKlasy{ ; private: public: deklaracje składowych (pól - danych) prototypy metod lub definicje metod

3 Klasy - podsumowanie poznanych wiadomości Definicje metod mogą: a) występować w obrębie deklaracji klasy, b) lub deklaracja klasy zawiera jedynie prototypy, a właściwe definicje podaje się poza klasą kwalifikując nazwę metody operatorem zasięgu i nazwą klasy Klasa może być zapisana w osobnym pliku File->New->Class dodajemy do projektu plik w którym zapisywana będzie klasa. W oknie edycyjnym nadajemy mu nazwę taką jak klasa która ma być w nim zapisana np. Wektor. Otrzymujemy 2 pliki : Wektor.h plik nagłówkowy w którym zapisujemy deklaracje klasy tj. pola i nagłówki metod Wektor.cpp plik implementacyjny w którym definiujemy metody klasy Wektor, poprzedzając je nazwą klasy z operatorem zasięgu Wektor:: Zarówno w piku Wektor.cpp jak i pliku zawierającym f-cję main musimy dołączyć naszą klasę poprzez #include Wektor.h

Destruktory 4 Destruktor jest funkcją, którą wykonuje się w celu zwolnienia pamięci przydzielonej dodatkowym obiektom lub innych zasobów. Jest on wywoływany automatycznie przez system podczas usuwania obiektu. Destruktora można czasem w ogóle nie definiować. Jeśli go jednak definiujemy, to jego nazwą jest nazwa klasy poprzedzona znakiem tyldy: MojaKlasa: class MojaKlasa { ; MojaKlasa();//to jest konstruktor ~MojaKlasa();//a to - destruktor Destruktor nie posiada argumentów. Jedna klasa może mieć tylko jeden destruktor.

Destruktory 5 Najczęstszą funkcją destruktora jest zwolnienie pamięci (zwykle poprzez zniszczenie wszystkich pól używanych przez ten obiekt). Destruktor zachowuje się jak zwykła metoda, tyle tylko, że jest wywoływany automatycznie podczas usuwania obiektu z pamięci. Samo wywołanie destruktora obiektu nie niszczy: wykonuje on to i tylko to, co zapisane jest w jego kodzie. Możemy jawnie wywołać destruktor na rzecz istniejącego obiektu. Niszczenie obiektów lokalnych, utworzonych na stosie zachodzi, gdy sterowanie wychodzi z bloku, w którym były zdefiniowane. Stos jest wtedy zwijany do stanu, w jakim był przy wejściu do danego bloku (funkcji). Usunięte zatem zostaną wszystkie zmienne utworzone na stosie w tym bloku, wśród nich również zmienne obiektowe. Usuwanie obiektów na stosie odbywa się w kolejności odwrotnej do ich kreowania jako pierwsze zostaną zatem zniszczone te, które utworzone były jako ostatnie.

Destruktory 6 class Klasa { int a; public: Klasa() {a=0; cout<<"konstruktor bezparam, a="<<a<<endl; Klasa(int aa) {a=aa; cout<<"konstruktor z param, a="<<a<<endl; int geta()const {return a; void seta(int aa) {a=aa; ~Klasa() {cout<<"destruktor a="<<a<<endl; ;

Destruktory 7 int main() { Klasa k1; Klasa k2 = Klasa(); k2.seta(1); Klasa k3(2); Klasa k4 = Klasa(3); konstruktor bezparam, a=0 konstruktor bezparam, a=0 konstruktor z param, a=2 konstruktor z param, a=3 destruktor a=3 destruktor a=2 destruktor a=1 destruktor a=0

Pola statyczne 8 Szczególny rodzaj pól to pola statyczne. Deklaruje się je ze specyfikatorem static. Oznacza on, że będzie utworzona tylko jedna zmienna o tej nazwie i że nazwa ta będzie leżeć w zasięgu klasy. Zmienna ta jest niezależna od obiektów (zmiennych) klasy, można z niej korzystać nawet, jeśli żaden obiekt tej klasy nie został utworzony. Sama deklaracja pola statycznego w klasie nie tworzy tej zmiennej (bo jest tylko deklaracją, a nie definicją). Zmienne odpowiadające polom niestatycznym (instancyjnym) są tworzone podczas tworzenia obiektów klasy. Zmienne statyczne trzeba utworzyć, czyli zdefiniować na zewnątrz klasy. Ponieważ jej nazwa należy do zasięgu klasy, poza klasą trzeba się do tej zmiennej odnieść poprzez jej nazwę kwalifikowaną, za pomocą operatora zasięgu klasy, ' ::'. W definicji poza klasą nie powtarzamy już specyfikatora static.

9 Pola statyczne Definiując zmienną statyczną klasy można (choć nie trzeba) ją zainicjować. Na przykład: class D { ; static int k1; // deklarujemy statyczne składowe klasy static int k2; int D::k1; // definicja; domyślne inicjowanie zerem int D::k2 = 7; // definicja z inicjowaniem

Pola statyczne 10 Wyjątkowo, składowe statyczne mogą być definiowane i inicjalizowane bezpośrednio w punkcie deklaracji, wewnątrz klasy, ale tylko jeśli są stałymi(const) i typu całkowitego class D { ; static const int k1, k2 = 2; //... const int D::k1 = 1; Tu k2 jest tworzone i inicjalizowane wewnątrz definicji klasy D, natomiast k1 tylko deklarowane, dlatego definicja z ostatniej linii jest konieczna, i to wraz z inicjalizacją, bo stałe muszą być inicjalizowane w momencie ich definiowania. Zmienne statyczne są tworzone (i inicjowane) po załadowaniu programu do pamięci, ale przed rozpoczęciem wykonywania funkcji main (jak zmienne globalne).

Pola statyczne 11 Do zmiennych statycznych klasy można się odwoływać w programie: poprzez ich pełną nazwę kwalifikowaną (D::k1) lub tak jak do normalnej składowej, czyli poprzez nazwę dowolnego obiektu tej klasy i operator wyboru składowej (kropka lub strzałka, w zależności od tego, czy nazwa była nazwą obiektu czy wskaźnika do niego). Oczywiście, ponieważ istnieje tylko jeden egzemplarz zmiennej statycznej, nie ma wtedy znaczenia, którego obiektu użyjemy. PODSUMOWANIE Składowe (pola i metody) niestatyczne (instancyjne) zawsze wiążą się z istnieniem obiektu danej klasy. Składowe statyczne (klasowe) tzn. ze specyfikatorem static nie dotyczą obiektów, ale całej klasy są wspólne dla wszystkich obiektów tej klasy mogą być używane nawet wtedy, gdy nie istnieje żaden obiekt klasy

12 Pola statyczne przykład licznik obiektów class Wektor { private: double x, y, z; //prywatne pola klasy static int ile; //licznik obiektów (instancji) klasy Wektor public: //sekcja publiczna Wektor();//bezparametrowy, zeruje pola Wektor(double xx, double yy, double zz); ~Wektor();//destruktor static int ilewektorow(); //metoda która istnieje dla klasy // a nie obiektu ; //pozostałe metody jak poprzednio //... int Wektor::ile =0; // definicja zmiennej statycznej z inicjowaniem

Pola statyczne przykład licznik obiektów 13 int Wektor:: ilewektorow() { return ile; Wektor:: Wektor(){ x = 0; y = 0; z = 0;//zerujemy pola klasy ile++; cout<<"***konstruktor bezparametrowy***, obiekt" << ilewektorow()<<endl; Wektor:: Wektor(double xx, double yy, double zz){ x = xx; y = yy; z = zz; ile++; cout<<"***konstruktor zwykly z bezparametrami***, obiekt" <<ilewektorow()<<endl; Wektor:: ~Wektor(){ cout<<"***destruktor ***, obiekt"<<ilewektorow()<<endl; ile--;

14 Pola statyczne przykład licznik obiektów int main(){ cout<<"liczba obiektow: "<< Wektor::ileWektorow() <<endl; //liczba obiektow: 0 //deklarujemy obiekt (instancje) klasy Wektor Wektor w1; //***konstruktor bezparametrowy***, obiekt 1 w1.wyswietl();//[ 0.0, 0.0, 0.0 ] //kolejny obiekt klasy Wektor Wektor w2(2,4,5); //***konstruktor zwykly z parametrami***, obiekt 2 w2.wyswietl(); //[ 2.0, 4.0, 5.0 ] Wektor w3 = w1.suma(w2); //***konstruktor zwykly z parametrami***, obiekt 3 w3.wyswietl();//[ 2.0, 4.0, 5.0 ] return 0; ***destruktor ***, obiekt 3 ***destruktor ***, obiekt 2 ***destruktor ***, obiekt 1

15 Wskaźnik this W C++ this jest nazwą ustalonego wskaźnika do obiektu na rzecz którego wykonywana jest metoda. Nazwą tego obiektu jest zatem *this. (* -operator dereferencji) Słowo kluczowe this może być użyte wyłącznie w metodach (niestatycznych funkcjach składowych), konstruktorach i destruktorze klasy. Do składowej sklad obiektu metoda (konstruktor, destruktor) może odwoływać się poprzez pełną nazwę tego obiektu, czyli używając notacji this->sklad lub (*this).sklad. Taka forma jest konieczna, jeśli wewnątrz funkcji zadeklarowaliśmy zmienną o tej samej nazwie, co któraś ze składowych klasy. Nazwa niekwalifikowana odnosi się wtedy do tej zmiennej lokalnej, a nie do składowej (zmiennymi lokalnymi są też zmienne skojarzone z parametrami funkcji).

Wskaźnik this 16 class MojaKlasa { double x; //składowa domyślnie prywatna public: void set(double); ; void MojaKlasa::set(double x) { this->x = x; //lub (*this).x = x;

17 Przeciążenia operatorów za pomocą metod klasy Operatory dwuargumentowe Aby przeciążyć operator @ w klasie Klasa definiujemy metodę o prototypie lub Typ operator@(typarg); Typ operator@(typarg&); Przykład 1. W klasie Wektor zadeklarować przeciążony operator == porównujący współrzędne wektora dla którego wykonujemy porównanie (lewa strona operatora) ze współrzędnymi wektora przekazanego jako parametr: bool operator==(const Wektor &w) const; Implementacja: bool Wektor ::operator==(const Wektor &w) const { return x==w.x && y==w.y && z==w.z;

18 Przeciążenia operatorów za pomocą metod klasy- przykład Przykład 2. Zadeklarować przeciążony operator + : Wektor operator+(const Wektor &w) const; która zwraca w wyniku wektor będący sumą wektora dla którego jest wykonywana metoda oraz wektora przekazanego przez parametr: Wektor Wektor ::operator+(const Wektor &w) const{ return Wektor(x+w.x, y+w.y, z+w.z); Przykład 3. Zdefiniuj przeciążenie operatora zwracającego wektor przeciwny do wektora na rzecz którego wykonywany jest operator: Wektor operator-()const; //deklaracja Wektor Wektor::operator-() const{ //definicja return Wektor(-x,-y,-z);

19 Przeciążenia operatorów za pomocą metod klasy- przykład Wówczas w funkcji main() np.: int main(){ Wektor a(1,1,1); Wektor b(2,2,2); if(a==b)//przeciążony operator== zamiast a.rowne(b) cout<<"a==b"<<endl; else cout<<"a!=b"<<endl; Wektor s1 = a.suma(b); s1.wyswietl(); //suma z wykorzystaniem operatora przeciążonego Wektor s = a+b; s.wyswietl(); //[3.0, 3.0, 3.0] Wektor pd = -b;

20 #include <string> using namespace std; class Kot { private: string imie; int wiek; double waga; public: Klasa Kot plik nagłówkowy Kot.h Kot();//konstruktor pusty tworzący obiekt kot //o imieniu wadze 0kg i wieku 0 lat Kot(const Kot &k); //konstruktor kopiujacy Kot(string i, int w, double wa); //konstruktor z //parametrami tworzący kota o zadanym imieniu, wadze i // wieku

; Klasa Kot plik nagłówkowy Kot.h //fcja ustawia pola na dane parametrami void Ustaw( string i, int w, double wa); //fcje zwracające wartości poszczególnych pól string zwrocimie()const; int zwrocwiek()const; double zwrocwage()const; //kot miauczy void dajglos() const; //f-cja logiczna sprawdzająca czy kot jest starszy //od kota danego parametrem bool starszyod(const Kot &k) const; //przeciążony operator > true jeśli kot jest starszy //od kota danego parametrem bool operator >(const Kot & k)const; 21

22 Klasa Kot plik implementacyjny Kot.cpp #include <iostream> #include "Kot.h" using namespace std; Kot::Kot() { imie = ""; wiek = 0; waga = 0; Kot::Kot(const Kot &k) { imie = k.imie; wiek = k.wiek; waga = k.waga; Kot::Kot(string i, int w, double wa) { imie = i; wiek = w; waga = wa; void Kot::Ustaw(string i, int w, double wa) { imie = i; wiek = w; waga = wa;

23 Klasa Kot plik implementacyjny Kot.cpp string Kot::zwrocImie()const { return imie; int Kot::zwrocWiek()const { return wiek; double Kot::zwrocWage()const { return waga; void Kot::dajGlos() const { cout << "Miau";

Klasa Kot plik implementacyjny Kot.cpp 24 bool Kot::starszyOd(const Kot &k) const { return wiek > k.wiek; bool Kot:: operator>(const Kot & k)const { return wiek > k.wiek;

25 #include <iostream> #include "Kot.h" using namespace std; Klasa Kot main() int main() { Kot f; f.ustaw("filus", 2, 2); Kot k("mruczek", 5, 4); if (f.starszyod(k))//lub if (f > k) cout << "starszy jest " << f.zwrocimie()<<endl; else cout << "starszy jest " << k.zwrocimie()<<endl; Kot t = f;//przypisanie obiektów cout << t.zwrocimie(); starszy jest Mruczek Filus

26 Wskaźniki do zmiennych Wartością zmiennej wskaźnikowej (ang. pointers) jest adres innej zmiennej. Zazwyczaj, określając typ zmiennej wskaźnikowej musimy określić też typ tych zmiennych, których adresy dana zmienna wskaźnikowa może przechowywać (związane jest między innymi z tym, że musi być znana długość (w bajtach) tego typu zmiennych). Deklaracja wskaźnika ma postać lub lub Typ *nazwa; Typ* nazwa; Typ * nazwa; Zmienna o nazwie nazwa będzie zmienną wskaźnikową przystosowaną do przechowywania adresów innych zmiennych, ale koniecznie typu Typ.

27 Przykład 1: Wskaźniki do zmiennych /*Deklarujemy i definiujemy (przydzielamy pamięć na) trzy zmienne typu double*/ double x, y = 1.5, u; /*Wprowadzamy zmienną wskaźnikową przystosowaną do przechowywania adresów zmiennych typu double:*/ double *px; /*px jest wskaźnikiem do zmiennej typu double. Natomiast zmienną, której adres jest wartością zmiennej wskaźnikowej, nazywamy zmienną wskazywaną przez ten wskaźnik. Wartość utworzonego wskaźnika px jest nieokreślona, to znaczy nie został tam wpisany adres żadnej istniejącej zmiennej typu double*/

28 Wskaźniki do zmiennych /*Jak przypisać zmiennym wskaźnikowym wartości(wpisać do nich adresy istniejących zmiennych typu double): */ px = &x; /*Do px wpisaliśmy adres zmiennej x typu double(zmienna x już istnieje, ma więc ma adres, mimo że jej wartość jest wciąż nieokreślona. Znak ' &' pełni rolę operatora wyłuskania adresu i działa na wyrażenie po swojej prawej stronie (musi to być wyrażenie identyfikujące daną, która ma określony, dostępny w programie adres w pamięci). Jeśli var jest identyfikatorem zmiennej, to wartością wyrażenia &var jest adres tej zmiennej.*/ double* py = &y /*Wskaźnik py deklarujemy i od razu inicjujemy adresem istniejącej y (wartością zmiennej wskazywanej przez py, czyli zmiennej y, jest 1.5)*/

29 double *pz, *pu = &u, v; Wskaźniki do zmiennych /*Deklarując w jednej instrukcji dwa lub więcej wskaźników, należy identyfikator każdego z tych wskaźników poprzedzić gwiazdką. Zmienna v jest typu double, a nie wskaźnikowego. Jak poprzez wskaźnik do zmiennej można dostać się do samej zmiennej? Robi się to poprzez operator dereferencji, zwany też operatorem wyłuskania wartości, oznaczany przez gwiazdkę. Jeśli pvar jest identyfikatorem wskaźnika, to wyrażenie *pvar jest nazwą zmiennej wskazywanej przez pvar. Zatem, ponieważ *py jest nazwą zmiennej wskazywanej przez py, więc jest w tej chwili inną nazwą zmiennej y */ cout << "*py = " << *py << " y = " << y << endl; /*to drukując wartość *py drukujemy 1.5 aktualną wartość y *py = 1.5 y = 1.5 */

Wskaźniki do zmiennych /*Analogicznie, przypiszmy zmiennej x wartość 0.5. Drukując teraz wartość *px drukujemy wartość zmiennej wskazywanej przez px, czyli w tej chwili zmiennej x, czyli 0.5 */ x = 0.5; cout << "*px = " << *px << " x = " << x << endl; //*px = 0.5 x = 0.5 /* Zauważmy, że *px, będąc nazwą zmiennej typu double wskazywanej przez px, może być użyte po lewej stronie przypisania. */ *px = 5*x; /*Ponieważ w tej chwili px wskazuje na x, jest to równoważne przypisaniu x = 5*x zatem drukując wartości x i *px otrzymujemy to samo */ cout << "*px = " << *px << " x = " << x << endl; //*px = 2.5 x = 2.5 30

Wskaźniki do zmiennych /*Wskaźnikowi pz przypiszmy wartość wskaźnika px, czyli adres zmiennej x */ pz = px; //Zatem w tej chwili x, *px i *pz oznaczają to samo cout << *pz = " << *pz << endl; //*pz = 2.5 cout << "py = " << py << endl; //Zmienna ta jest zmienną wskaźnikową, więc jej wartością jest adres zmiennej y. Zatem wstawienie py do strumienia wyjściowego spowoduje wypisanie adresu zmiennej y np. py = 0xbffffa30 A jaki adres ma sama zmienna py? Żeby to sprawdzić, możemy wydrukować wartość wyrażenia &py: wartością tą jest właśnie adres zmiennej py (a nie adres będący wartością py): */ cout << "&py = " << &py << endl; //np. &py = 0xbffffa18 31

Wskaźniki do zmiennych Przykład 2.Deklarujemy dwie zmienne x i y typu double i dwa wskaźniki pmin i pmax typu double*. Następnie wczytujemy dwie liczby do zmiennych x i y, po czym ustawiamy wskaźniki pmin i pmax w ten sposób, aby pmin wskazywało ma mniejszą z liczb x i y, a pmax na większą z nich. Używając następnie operatora dereferencji drukujemy najpierw mniejszą, potem większą z liczb. #include <iostream> using namespace std; int main() { double x, y, *pmin, *pmax; cout << "Podaj dwie liczby: "; cin >> x >> y; if (x < y) { pmin = &x; pmax = &y; else { pmin = &y; pmax = &x; cout << "Min = " << *pmin << endl; cout << "Max = " << *pmax << endl; 32

Przykład klasy- Ulamek Napisz w pliku Ulamek.h deklarację klasy Ulamek, w której przechowujemy następujące informacje o ułamku: licznik i mianownik(>0) oraz metody pomocnicza metoda prywatna obliczająca NWD dwóch liczb całkowitych konstruktor bezparametrowy (ustawia ułamek 0/1) konstruktor ustalający wartość ułamka na podstawie parametru całkowitego konstruktor ustalający wartość ułamka na podstawie przekazanych przez parametry wartości licznika i mianownika metoda Ustaw ustalająca wartość ułamka na podstawie przekazanych przez parametry wartości licznika i mianownika metoda Skroc skracająca ułamek metoda tostring zwracająca reprezentację tekstową ułamka w formie l/m metody PodajMianownik i PodajLicznik zwracające wartości odpowiednich pól klasy metodę Suma zwracającą w wyniku ułamek będący sumą ułamka na rzecz którego wykonywana jest metoda i ułamka przekazanego przez parametr metodę Iloczyn zwracającą w wyniku ułamek będący iloczynem ułamka na rzecz którego wykonywana jest metoda i ułamka przekazanego przez parametr oraz operatory dwuargumentowe + (suma),* (iloczyn) i == (równe). Napisz implementację powyższych metod w pliku Ulamek.cpp. Zadbaj, aby zawsze mianownik był >0. 33