18
Programski jezici 1 2. dio Elektrotehnički fakultet Banja Luka KLASE I APSTRAKCIJA PODATAKA Goran Banjac [email protected] 08/25/2022

C++ Klase

Embed Size (px)

DESCRIPTION

C++

Citation preview

Page 1: C++ Klase

Programski jezici 1

2. dio

Elektrotehnički fakultetBanja Luka

KLASE I APSTRAKCIJA PODATAKA

Goran [email protected]

04/22/2023

Page 2: C++ Klase

Klase – 2. dio

Sadržaj Konstantni objekti i konstantne članice klase Pokazivač this Kompozicija: OBJEKAT kao ATRIBUT Statički (zajednički) članovi klase

Page 3: C++ Klase

Konstantni objekti i konstantne članice

Konstantni objekti Konstantni objekti (read-only)

definišu se navođenjem ključne riječi const (kao i instance ugrađenih tipova).

Primjer:

class Time{ public: Time(int h=0,int m=0,int s=0)

{ hh=h; mm=m; ss=s; } private: int hh, mm, ss;

};...const Time podne(12);const Time ponoc; Svaki pokušaj da se promijeni

vrijednost konstantnog objekta biće okarakterisan kao sintaksna

greška!!!

Page 4: C++ Klase

Konstantni objekti i konstantne članice

Konstantne funkcije članice Da bi kompajler omogućio poziv

funkcije članice za konstantne objekte funkcija članica takođe mora biti definisana kao konstantna. (Ovo važi i za get funkcije!)

Funkcija članica se proglašava konstantnom tako što se (i u prototipu i u definiciji funkcije) iza liste parametara navede const.

Primjer:

class Time{ public: Time(int h=0,int m=0,int s=0)

{ hh=h; mm=m; ss=s; } int getSat() const; private: int hh, mm, ss;

};...int Time::getSat() const

{ return hh; }

Ako se za datu klasu neće definisati konstantni objekti, funkcije članice ne moraju da se definišu kao konstantne.

Ako se za neku klasu i definiše konstantan objekat, ali se za taj objekat neće pozivati funkcije članice, ni tada funkcije članice ne moraju da se definišu kao konstantne.

Za konstruktore i destruktore ne može da se koristi const!

Iz konstruktora je dozvoljeno i moguće pozivati funkcije članice koje nisu konstantne.

Page 5: C++ Klase

Konstantni objekti i konstantne članice

Primjer:#include <iostream>#include <cmath>#define K(a,b) pow(((a)-(b)),2)using namespace std;

class Tacka{ public: Tacka (double=0, double=0); double getX() const; double getY() const; double daljina(Tacka) const; void pisiTacka() const; private: double x, y;};

Tacka::Tacka(double xx, double yy) { x = xx; y = yy; }

double Tacka::getX() const { return x; }

double Tacka::getY() const { return y; }

double Tacka::daljina(Tacka t) const { return sqrt(K(x,t.x)+K(y,t.y)); }

void Tacka::pisiTacka() const { cout << "("<<x<<","<<y<<")"; }

int main(){ Tacka tA(3,4); const Tacka tO; // konstantan objekat

cout<<"A: "<<tA.getX()<<","<<tA.getY()<<endl;

cout<<"O: "<<tO.getX()<<","<<tO.getY()<<endl;

cout<<"A: "; tA.pisiTacka(); cout<<endl;

cout<<"O: "; tO.pisiTacka(); cout<<endl;

cout << "Udaljenost od A"; tA.pisiTacka(); cout << " do O"; tO.pisiTacka(); cout << " iznosi: " << tA.daljina(tO) << endl;

cout << "Udaljenost od O"; tO.pisiTacka(); cout << " do A"; tA.pisiTacka(); cout << " iznosi: " << tO.daljina(tA) << endl;}

A: 3,4O: 0,0A: (3,4)O: (0,0)Udaljenost od A(3,4) do O(0,0) iznosi: 5Udaljenost od O(0,0) do A(3,4) iznosi: 5

Page 6: C++ Klase

Konstantni objekti i konstantne članice

Konstantni podaci članovi Klasa može da sadrži i

konstantne podatke članove. Tada će kreirani objekti imati konstantne atribute.

Inicijalizacija konstantnih atributa ne može da se vrši u tijelu konstruktora korišćenjem operatora dodjele, već pomoću inicijalizatora.

Primjer:

class Brojac{

private: int stanje; const int korak; public:

Brojac(int b, int k) : korak(k) { stanje = b; }

};

Inicijalizacija atributa koji nisu konstantni takođe može da se vrši na isti način.

class Brojac{

private: int stanje; const int korak; public:

Brojac(int b, int k) : stanje(b), korak(k) {}; };

Page 7: C++ Klase

Konstantni objekti i konstantne članice

Primjer:

#include <iostream>using namespace std;

class Inkrement{ public: Inkrement( int b=0, int i=1 ); void dodaj() { stanje += korak; } void print(); private: int stanje; const int korak; };

Inkrement::Inkrement(int b,int i) : korak (i) { stanje = b; }

void Inkrement::print(){ cout << "stanje=" << stanje << ", korak=" << korak << endl;}

int main(){ Inkrement data(10,5); cout << "Prije petlje : "; data.print(); for ( int j=1; j<4; j++ ) { data.dodaj(); data.print(); }}

Prije petlje : stanje=10, korak=5stanje=15, korak=5stanje=20, korak=5stanje=25, korak=5

Page 8: C++ Klase

Pokazivač this

Osim formalnih argumenata, funkcije članice imaju i jedan “skriveni” argument (skriveni – ne vidi se u prototipu).

Taj “skriveni” argument je tekući objekat – objekat za koji je pozvana funkcija članica.

Adresa skrivenog argumenta (tekućeg objekta), za vrijeme izvršavanja funkcije članice, nalazi se u pokazivaču this.

Svaki objekat ima pristup svojoj vlastitoj adresi preko pokazivača this.

Pokazivač this koristi se implicitno za referenciranje članica i ne mora da se navodi (kao u dosadašnjim primjerima).

Pokazivač this može da se koristi i eksplicitno! Ako je tekući objekat vrijednost koju vraća data funkcija članica, Ako je tekući objekat argument neke funkcije, Za kaskadno pozivanje funkcija.

Page 9: C++ Klase

Pokazivač this

Primjer:#include <iostream>using namespace std;class Test { public: Test(int a=0) { x=a; }; void print() const; void maska(int) const; private: int x;};void Test::print() const{ cout << "x = " << x << endl; cout << "this->x = " << this->x << endl; cout << "(*this).x = " << (*this).x << endl;}void Test::maska(int x) const{ cout << "arg x = " << x << endl; cout << "clan x = " << this->x << endl;}int main(){ Test t(12); t.print(); t.maska(100); }

x = 12this->x = 12(*this).x = 12arg x = 100clan x = 12

Page 10: C++ Klase

Pokazivač this

Primjer:#include <iostream>using namespace std;class Time{ public: Time &setTime(int, int); Time &setSat(int); Time &setMin(int); void print(); private: int sat, min;}; Time &Time::setTime(int h, int m) { setSat(h); setMin(m); return *this; }Time &Time::setSat(int h) { sat = (h>=0 && h<24) ? h : 0; return *this;} Time &Time::setMin(int m){ min = (m>=0 && m<60) ? m : 0; return *this;}

void Time::print(){ cout << ( sat<10 ? "0":"" ) << sat; cout << ":" ; cout << ( min<10 ? "0":"" ) << min;}int main(){ Time t; t.setSat(18).setMin(5); cout << "Vrijeme : "; t.print(); cout << "\nNovo vrijeme : "; t.setTime(20,30).print();}

Vrijeme : 18:05Novo vrijeme : 20:30

Page 11: C++ Klase

Pokazivač thisPrimjer:#include <iostream>#include <cmath>using namespace std;

class Complex; double moduo(Complex);

class Complex { public: Complex(char s, double r=0, double i=0) : c(s), re(r), im(i) {}; double getRe() { return re; } double getIm() { return im; } void printComplex() { cout << c << "="; if (re!=0) { cout << re; if (im>0) cout << "+"; } if (im!=0) { if (im!=1) cout << im; cout << "i"; } cout << "\t|" << c << "|=" << moduo(*this) << endl; } private: double re, im; char c; };double moduo(Complex c) { return pow(pow(c.getRe(),2.0)+pow(c.getIm(),2.0),0.5); }int main(){ Complex a('a',1,1), b('b',2), c('c',0,1), d('d',3, -4); a.printComplex(); b.printComplex(); c.printComplex(); d.printComplex();}

a=1+i |a|=1.41421b=2 |b|=2c=i |c|=1d=3-4i |d|=5

Page 12: C++ Klase

Kompozicija: OBJEKAT kao ATRIBUT

Podatak član u nekoj klasi može da bude objekat (instanca neke klase). Kad neki objekat ima neki drugi objekat kao atribut, govorimo o

kompoziciji. Objekat može da sadrži jedan ili više objekata drugih klasa (automobil

ima točkove, sjedišta, volan, ...), tj. klasa može da sadrži više podataka članova koji su instance nekih drugih klasa.Primjer:

class Datum { public: Datum(int=1, int=1, int=2000); ~Datum(); private: int dan, mjesec, godina;};

class Osoba { public: Osoba(char *, int, int, int); ~Osoba(); private: char ime[15]; const Datum rodjen;};

Kompozicija ne može da postoji ako nema objekata koji je čine. Zato se prilikom kreiranja nekog složenog objekta (kompozicija), prvo kreiraju svi podobjekti, a zatim objekat koji ih sadrži (host objekat).

Prvo se pozivaju i izvršavaju konstruktori za podobjekte (redom kojim su navedeni u definiciji klase, a ne redom kojim su navedeni u listi inicijalizatora konstruktora host objekta), a na kraju konstruktor host objekta.

Page 13: C++ Klase

Kompozicija: OBJEKAT kao ATRIBUT

Primjer:#include <iostream>using namespace std;class X { public: X(int i=0) : x(i) { cout << "X"; } int getX() { return x; } private: int x;};class Y { public: Y(int i=0) : y(i) { cout << "Y"; } int getY() { return y; } private: int y;};class A { public: A(int i=1, int j=2, int k=3): a(k), x(i), y(j) { cout << "A" << endl; } void print() { cout << "Objekat klase A sadrzi:" << endl; cout << " podobjekat klase X: " << x.getX() << endl; cout << " podobjekat klase Y: " << y.getY() << endl; cout << " podatak tipa int: " << a << endl; } private: Y y; X x; int a;};int main() { A obj; obj.print(); }

YXAObjekat klase A sadrzi: podobjekat klase X: 1 podobjekat klase Y: 2 podatak tipa int: 3

Page 14: C++ Klase

Kompozicija: OBJEKAT kao ATRIBUT

Primjer:#include <iostream>using namespace std;class Datum { public: Datum(int d=1, int m=1, int g=2000) { gg = g; mm = (m>0 && m<=12) ? m : 1; dd = provjeriDan(d); cout<<"Kon. datuma: "; print(); } void print() const { cout<<dd<<'.'<<mm<<'.'<<gg<<'.'<<endl;} ~Datum() { cout<<"Dest. datuma: "; print(); } private: int dd, mm, gg; int provjeriDan(int dan) { static const int m[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; if (dan>0 && dan<=m[mm]) return dan; if (mm==2 && dan==29 && (gg%400==0 || (gg%4==0 && gg%100!=0))) return dan; return 1; }};

class Osoba { public: Osoba(char *s, int d, int m, int g) : rodjen(d,m,g) { int bs=0; while ((ime[bs]=*(s+bs)) && bs<14) bs++; if (bs==14) ime[bs]='\0'; cout <<"Kon. osobe : "<<ime<<endl; } void print() const { cout << ime << " je rodjen: "; rodjen.print(); } ~Osoba() { cout << "Dest. osobe : "<<ime<<endl; } private: char ime[15]; const Datum rodjen;};int main(){ Osoba otac ("Marko", 28,2,1975), sin ("Janko", 29,2,2000), pradeda("Slavko",29,2,1900); otac.print(); sin.print(); pradeda.print();}

Kon. datuma: 28.2.1975.Kon. osobe : MarkoKon. datuma: 29.2.2000.Kon. osobe : JankoKon. datuma: 1.2.1900.Kon. osobe : SlavkoMarko je rodjen: 28.2.1975.Janko je rodjen: 29.2.2000.Slavko je rodjen: 1.2.1900.Dest. osobe : SlavkoDest. datuma: 1.2.1900.Dest. osobe : JankoDest. datuma: 29.2.2000.Dest. osobe : MarkoDest. datuma: 28.2.1975.

Page 15: C++ Klase

Statički (zajednički) članovi klase

Prilikom definisanja klase, članice mogu da se proglase statičkim (kvalifikator static ispred članice).

Statički član klase je zajednički za sve objekte date klase koji su stvoreni tokom izvršavanja programa.

Članice klase koje nisu zajedničke, nazivaju se pojedinačne članice klase.

I podaci i funkcije članice mogu biti zajednički članovi klase.

Zajednički podaci članovi Ako je podatak član zajednički član

klase, to znači da postoji samo jedan primjerak tog atributa, bez obzira na broj objekata.

Pristup zajedničkom atributu je pristup istoj memorijskoj lokaciji za sve objekte.

Mijenjanjem vrijednosti zajedničkog atributa utiče se na stanje svih objekata te klase.

Primjer:

class Klasa { ... static int a; // zajednicki clan int b; // pojedinacni clan ...};// obavezna inicijalizacija statickog atributa

int Klasa::a = 55;

Page 16: C++ Klase

Statički (zajednički) članovi klase

Primjer:

#include <iostream>using namespace std;class Komuna { public: Komuna(char c) : naziv(c) { cout << ++brojac << ". objekat zove se: " << naziv << endl; } private: static int brojac; // ZP char naziv; // PP};int Komuna::brojac = 0; // inicijalizacija ZPint main() { Komuna a('A'), b('B'), c('C'); }

1. objekat zove se: A2. objekat zove se: B3. objekat zove se: C

Page 17: C++ Klase

Statički (zajednički) članovi klase

Zajedničke funkcije članice Zajedničke funkcije članice ne

posjeduju pokazivač this. Zajedničke funkcije članice

pristupaju zajedničkom atributu direktnim referenciranjem atributa.

Primjer:class Klasa { static int a; public: static int f() { cout << ++a; }};int Klasa::a=0;

Zajedničke funkcije članice pristupaju pojedinačnom atributu nekog objekta referenciranjem objekta kojem pripada taj atribut.

Primjer:class Klasa { int x; public: static int g(Klasa &a, Klasa *b) { cout << a.x; cout << b->x; }};

Pojedinačne funkcije članice mogu direktno da pristupe i pojedinačnim i zajedničkim atributima.

Page 18: C++ Klase

Statički (zajednički) članovi klase

Primjer:class Klasa { static int a; // ZP int b; // PP public: int h(int); // PF static int f(); // ZF static void g (Klasa, Klasa *, Klasa &); //

ZF};int Klasa::a=55; // inicijalizacija ZPint Klasa::f(){ int i=a; // ZF moze da pristupi ZP int j=b; // ERR - ZF ne moze da pristupi PP return i+j;}void Klasa::g(Klasa x, Klasa *y, Klasa &z){ int i = x.b; // ZF moze da pristupi int j = y->b; // PP konkretnih objekata z.b = i + j; }int Klasa::h( int x ) // PF moze da { return (a+b)*x; } // pristupa i PP i ZP

int main(){ // poziv ZF bez konkretnog objekta int p=Klasa::f(); // ERR - poziv PF ne moze bez objekta int q=Klasa::h(5); Klasa k; Klasa::g(k,&k,k); // poziv ZF int s=k.h(6); // poziv PF}