UVOD V OBJEKTNO PROGRAMIRANJE Razred class Objekt ki
UVOD V OBJEKTNO PROGRAMIRANJE Razred (class) Objekt, ki je osnova objektno orientiranih jezikov, je sestavljen iz podatkov in postopkov, ki se izvajajo nad temi podatki. POMNILNIK Fizični naslovi class CPravokotnik { int x, y; public: void set_values (int, int); int area () { return (x*y); } } pk; void CPravokotnik: : set_values (int a, int b) { x = a; y = b; } CPravokotnik je ime razreda, pk pa je deklarirani objekt tega razreda. (Deklaracijo objektov lahko opravimo tudi kasneje. ) V telesu navedemo člane, ki so lahko deklaracije spremenljivk, deklaracije prototipov funkcij (lahko so tudi definicije vrinjenih funkcij), in pa določila pravice dostopa do članov. Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Razred (class) Objekt, ki je osnova objektno orientiranih jezikov, je sestavljen iz podatkov in postopkov, ki se izvajajo nad temi podatki. class CPravokotnik { int x, y; public: void set_values (int, int); int area () { return (x*y); } } pk; POMNILNIK Fizični naslovi Vsebina { return x*y; } 0 x 0040 FF 6 C Logični naslovi pk. area() pk. set_values(int, int) pk. y 0 x 0042042 C pk. x void CPravokotnik: : set_values (int a, int b) { x = a; y = b; } CPravokotnik je ime razreda, pk pa je deklarirani objekt tega razreda. (Deklaracijo objektov lahko opravimo tudi kasneje. ) V telesu navedemo člane, ki so lahko deklaracije spremenljivk, deklaracije prototipov funkcij (lahko so tudi definicije vrinjenih funkcij), in pa določila pravice dostopa do članov. 0 x 0040 FF 6 C Zaslon { x=a; y=b; } : : set_values (int a, int b)
UVOD V OBJEKTNO PROGRAMIRANJE Pravico dostopa do posameznih članov definiranega razreda določimo z naslednjimi določili: private, člani razreda so dosegljivi samo iz metod tega razreda in iz prijateljskih metod (friends). protected, člani razreda so dosegljivi iz metod tega razreda, iz prijateljskih metod in iz izpeljanih razredov. public, člani razreda so dosegljivi iz vseh metod, iz katerih je objekt viden. Vsi člani razreda, definiranega s ključno besedo class, imajo privzeto private dostop. Do članov deklariranega objekta pravokot x in y ne moremo dostopati iz metod, ki niso člani razreda CPravokotnik, ker imata definiran private dostop. Z operatorjem dosega (: : ) povemo prevajalniku, da gre za funkcijo, ki je član razreda CPravokotnik in ne za navadno globalno funkcijo. int main () { CPravokotnik pk 1, pk 2; pk 1. set_values (3, 4); pk 2. set_values (5, 6); cout << “ploscina: " << pk 1. area(); cout << “ploscina: " << pk 2. area(); return 0; } POMNILNIK Fizični naslovi Vsebina { return x*y; } 0 x 0040 FF 6 C Logični naslovi pk. area() pk. set_values(int, int) pk. y 0 x 0042042 C 0 x 0040 FF 6 C Zaslon pk. x { x=a; y=b; } : : set_values (int a, int b)
UVOD V OBJEKTNO PROGRAMIRANJE Pravico dostopa do posameznih članov definiranega razreda določimo z naslednjimi določili: private, člani razreda so dosegljivi samo iz metod tega razreda in iz prijateljskih metod (friends). protected, člani razreda so dosegljivi iz metod tega razreda, iz prijateljskih metod in iz izpeljanih razredov. public, člani razreda so dosegljivi iz vseh metod, iz katerih je objekt viden. Vsi člani razreda, definiranega s ključno besedo class, imajo privzeto private dostop. Do članov deklariranega objekta pravokot x in y ne moremo dostopati iz metod, ki niso člani razreda CPravokotnik, ker imata definiran private dostop. Z operatorjem dosega (: : ) povemo prevajalniku, da gre za funkcijo, ki je član razreda CPravokotnik in ne za navadno globalno funkcijo. int main () { CPravokotnik pk 1, pk 2; pk 1. set_values (3, 4); pk 2. set_values (5, 6); cout << “ploscina: " << pk 1. area(); cout << “ploscina: " << pk 2. area(); return 0; } POMNILNIK Fizični naslovi Vsebina { return x*y; } 0 x 0040 FF 6 C Logični naslovi pk. area() pk. set_values(int, int) pk. y 0 x 0042042 C pk. x { return x*y; } 0 x 0040 FF 6 C 0 x 00420434 pk 1. area() pk 1. set_values(int, int) 4 pk 1. y 3 pk 1. x { return x*y; } 0 x 0040 FF 6 C pk 2. area() pk 2. set_values(int, int) 6 pk 2. y 0 x 0042043 C 5 pk 2. x 0 x 0040 FF 6 C { x=a; y=b; } ploscina: 12 ploscina: 30 Zaslon : : set_values (int a, int b)
UVOD V OBJEKTNO PROGRAMIRANJE Konstruktor in destruktor POMNILNIK Fizični naslovi Da bi preprečili vračanje nedoločenih vrednosti podatkovnih članov objekta, lahko kot en član razreda definiramo t. i. funkcijo konstruktor, ki se bo avtomatsko izvršila ob vsaki deklaraciji novega objekta tega razreda. Konstruktorska funkcija ima enako ime kot razred ter nima določenega podatkovnega tipa (tudi void ne) in se je ne da poljubno klicati. - konstruktor je metoda razreda, ki ima enako ime kot razred - konstruktor je metoda razreda, ki ničesar ne vrača - razred ima lahko več konstruktorjev - konstruktor se izvede ob deklaraciji objekta. Funkcija destruktor je predvsem namenjena sprostitvi dinamičnega pomnilnika v primeru dinamičnega zaseganja, izvršila pa se bo ob izteku življenjske dobe objekta. Destruktorska funkcija ima prav tako enako ime kot razred, vendar ima pred imenom dodan še znak tilda (~) ter tudi ne vrača rezultat. - destruktor je metoda razreda, ki ima enako ime kot razred in dodan prvi znak '~ ' - destruktor je metoda razreda, ki nič ne vrača in nič ne sprejme - razred ima lahko samo en destruktor - destruktor se izvede, ko se objekt uniči Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE #include<iostream. h> const float pi = 3. 14; POMNILNIK Fizični naslovi Vsebina { return (…); } class CKrozec { float *polmer; public: CKrozec (float); ~CKrozec (); float area () {return (*polmer * 2 * pi); } }; CKrozec: : CKrozec (float r) { polmer = new float; *polmer = r; } krozec. A. area() krozec. A. ~CKrozec() krozec. A. CKrozec(float) 0 x 0012 FF 88 1 { return (…); } krozec. A. x krozec. B. area() krozec. B. ~CKrozec() krozec. B. CKrozec(float) 0 x 0012 FF 84 2. 5 CKrozec: : ~CKrozec () { delete polmer; } int main () { CKrozec krozec. A(1), krozec. B(2. 5); cout << "krozec. A area: " << krozec. A. area() << endl; cout << "krozec. B area: " << krozec. B. area() << endl; return 0; } Logični naslovi krozec. A area: 6. 28 krozec. B area: 15. 7 Zaslon krozec. B. x
UVOD V OBJEKTNO PROGRAMIRANJE Prekriti konstruktor Razred ima lahko več konstruktorjev. Enako kot vse druge funkcije tudi konstruktor je lahko prekrit z več funkcijami, ki imajo enako ime vendar različne tipe ali različno število formalnih argumentov. Vemo, da bo izmed prekritih funkcija prevajalnik poklical tisto, katere formalni argumenti se ujemajo po tipu in številu z dejanskimi. V primeru konstruktorjev, ki so avtomatsko poklicani ob deklaraciji objekta, se bo torej izvršil tisti, katerega argumenti se bodo ujemali z navedenimi v deklaraciji: POMNILNIK Fizični naslovi class CPravokotnik { int X, Y; public: CPravokotnik (); CPravokotnik (int, int); int area (void) { return ( X * Y ); } }; CPravokotnik: : CPravokotnik () { X = 5; Y = 5; } CPravokotnik: : CPravokotnik (int a, int b) { X = a; Y = b; } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Privzeti konstruktor V primeru, da v definiciji razreda ne deklariramo nobenega konstruktorja, bo prevajalnik sam ustvaril privzeti konstruktor, ki pa bo brez argumentov. Npr: class CPrimer { public: int a, b, c; void produkt (int n, int m) { a=n; b=m; c=a*b; }; }; V zgornjem primeru bo prevajalnik ustvaril privzeti konstruktor, kar nam pa omogoča, da lahko objekte razreda deklariramo brez argumentov: CPrimer test; Toda takoj, ko v razredu mi sami deklariramo svoj lastni konstruktor, nam prevajalnik več ne ustvari privzetega konstruktorja. Zato moramo navesti vse člane tega razreda, tako kot smo jih definirali v prototipu konstruktorja: class CPrimer { public: int a, b, c; CPrimer (int n, int m) { a=n; b=m; }; void produkt () { c=a*b; }; }; POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Ker smo v prejšnjem primeru deklarirali konstruktor z dvema argumentoma tipa int, se bo pravilna deklaracija objekta glasila: CPrimer test (2, 3); medtem ko: CPrimer test; ne bo več pravilna deklaracija, ker smo privzeti konstruktor, ki ga bi sicer prevajalnik sam ustvaril, nadomestili z našim konstruktorjem. Toda, privzeti konstruktor ni edina funkcija, ki jo prevajalnik sam ustvari. To so še copy constructor, copy assignment operator in pa privzeti destruktor. Funkciji copy constructor in copy assignment operator prekopirata vse podatke iz drugega objekta v podatkovne člane trenutnega objekta. copy constructor implicitno deklariran s strani prevajalnika v primeru razreda CExample, bi se glasil takole: CPrimer: : CPrimer (const CPrimer& rv) { a=rv. a; b=rv. b; c=rv. c; } Zato bosta pravilni obe naslednji deklaraciji: CPrimer test 1 (2, 3); CPrimer test 2 (test 1); POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Kazalci na razrede CPravokotnik * k_p; Deklarirani kazalec k_p je kazalec, ki kaže na objekt razreda CPravokotnik. Za dostopanje do vsebine nekega člana deklariranega objekta, na katerega kaže kazalec, uporabimo dereferenčni operator puščico (->). Primer programa: #include <iostream. h> class CPravokotnik { int X, Y; public: void set_values (int, int); int area (void) {return (X * Y); } }; void CPravokotnik: : set_values (int a, int b) { X = a; Y = b; } int main () { CPravokotnik a; CPravokotnik * d = new CPravokotnik[2]; a. set_values (1, 2); d->set_values (5, 6); d[1]. set_values (7, 8); cout << "a area: " << a. area() << endl; cout << "d[0] area: " << d[0]. area() << endl; cout << "d[1] area: " << d[1]. area() << endl; return 0; } POMNILNIK Fizični naslovi Vsebina Logični naslovi { return X*Y; } a. area() a. set_values(int, int) a. y 0 x 0012 FF 84 0 x 0012 FF 80 a. x 0 x 00 A 1370 C { return X*Y; } d d[1]. area() d[1]a. set_values(int, int) d[1]. y 0 x 00 A 13714 d[1]. x { return X*Y; } d[0]. area() d[0]a. set_values(int, int) d[0]. y 0 x 00 A 1370 C Zaslon d[0]. x
UVOD V OBJEKTNO PROGRAMIRANJE Prekriti operatorji Standardni operatorji za izvajanje operacij z osnovnimi tipi so že definirani znotraj jezika C++. Na primer: int a, b, c; a = b + c; Za izvajanje operacij z lastnimi tipi, ki jih sami definiramo kot strukture ali razrede, pa lahko sami definiramo tudi svoje operatorje. struct vsota { string produkt; float znesek; } a, b, c; a = b + c; V zgornjem primeru nam bo prevajalnik javil napako, ker nimamo definiranega operatorja seštevanja za seštevanje objektov strukture. Jezik C++ nam omogoča izdelavo lastnih prekritih operatorjev za naslednje standardne operatorje: +, -, *, /, =, <, >, +=, -=, *=, /=, <<, >>, =, >>=, ==, !=, <=, >=, ++, --, %, &, ^, !, |, ~, &=, ^=, |=, &&, ||, %=, [], (), , , ->*, ->, new, delete, new[], delete[]. Izdelavo prekritega operatorja opravimo z definicijo operatorske funkcije, katere ime je sestavljeno iz ključne besede operator ter operatorskega znaka, ki ga želimo “prekriti”. Sintaksa je: tip operator znak (parametri) { /*. . . */ } POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Prekriti operatorji Primer uporabe prekritega operatorja +. Definirali bomo razred za delo z dvodimenzionalnimi vektorji ter napisali operatorsko funkcijo za seštevanje vektorjev, npr. : a(3, 1) in b(1, 2). Pri seštevanju dveh dvodimenzionalnih vektorjev posebej seštejemo x koordinati in posebej y koordinati. Rezultat seštevanja vektorjev iz zgornjega primera bo torej (3+1, 1+2) = (4, 3). #include <iostream. h> class CVektor { public: int x, y; CVektor () {}; CVektor (int, int); CVektor operator + (CVektor); }; CVektor: : CVektor (int a, int b) { x = a; y = b; } CVektor: : operator+ (CVektor vtr) { CVektor temp; temp. x = x + vtr. x; temp. y = y + vtr. y; return (temp); } int main () { CVektor a (3, 1), b (1, 2); CVektor c = a + b; cout << c. x << ", " << c. y; return 0; } POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Funkcija operator+ razreda CVektor je prekriti operator +. Lahko jo pokličemo implicitno, kot operator ali eksplicitno, kot funkcijo: c = a + b; c = a. operator+ (b); V razredu je definiran tudi konstruktor brez parametrov in s praznim blokom: CVektor () { }; To je potrebno, ker je eksplicitno deklariran tudi konstruktor: CVektor (int, int); kar pomeni, da prevajalnik ne bo kreiral privzetega konstruktorja, ki ga pa potrebujemo za deklaracijo objekta brez parametrov. Vendar je deklaracija konstruktorja s praznim blokom slaba rešitev, ker ne zagotavlja minimalne funkcionalnosti, ki jo običajno pričakujemo od konstruktorja. Boljša rešitev bi bila: CVektor () { x=0; y=0; }; Omenili smo že, da prevajalnik sam ustvari tudi privzeto funkcijo prireditvenega operatorja =, z razredom kot parametrom. Zato lahko zapišemo: CVektor d (2, 3); CVektor e; e = d; Privzeti funkciji prireditvenega operatorja lahko po potrebi tudi zapišemo prekrito funkcijo, npr. za kopiranje le določenih članov razreda ali izvedbo dodatne inicializacije. POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Kazalec this kaže na objekt, katerega funkcija se trenutno izvaja (vsebuje fizični naslov te funkcije). Primer: POMNILNIK Fizični naslovi #include <iostream. h> class CDummy { public: int isitme (CDummy& param); }; int CDummy: : isitme (CDummy& param) { if (¶m == this) return true; else return false; } int main () { CDummy a; CDummy* b = &a; if ( b->isitme(a) ) cout << "yes, &a is b"; return 0; } Običajno ga uporabljamo v funkcijah, ki vračajo objekte po referenci (izogibajoč se uporabi začasnih objektov). Na ta način lahko zapišemo prekriti prireditveni operator, npr: CVektor& CVektor: : operator= (const CVektor& vtr) { x=vtr. x; y=vtr. y; return *this; } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Statični člani razreda POMNILNIK Fizični naslovi Razred lahko vsebuje tudi static člane, ki so lahko tako podatki kot funkcije. Statični podatkovni člani razreda imajo enako vrednost v vseh objektih istega razreda. Takšno spremenljivke npr. lahko uporabimo za indikacijo števila trenutno deklariranih objektov razreda: #include <iostream. h> class CDummy { public: static int n; CDummy () { n++; }; ~CDummy () { n--; }; }; int CDummy: : n=0; int main () { CDummy a; CDummy b[5]; CDummy * c = new CDummy; cout << a. n << endl; delete c; cout << CDummy: : n << endl; return 0; } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Prijateljske funkcije Praviloma do private in protected članov razreda ne moremo dostopati izven razreda, v katerem so deklarirani. To lahko spremenimo preko “prijateljev”. Če želimo neko zunanjo funkcijo deklarirati kot prijatelja razreda, kar ji bo omogočilo dostop do private in protected članov tega razreda, to storimo z deklaracijo prototipa te zunanje funkcije znotraj razreda in z določilom friend. class CPravokot { int x, y; public: void set_values (int, int); int area () {return (x * y); } friend CPravokot duplicate (CPravokot); }; void CPravokot: : set_values (int a, int b) { x = a; y = b; } CPravokot duplicate (CPravokot pk) { CPravokot pk 2; pk 2. x = pk. x*2; pk 2. y = pk. y*2; return (pk 2); } int main () { CPravokot pk. A, pk. B; pk. A. set_values (2, 3); pk. B = duplicate (pk. A); cout << pk. B. area(); return 0; } POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Prijateljski razredi Razredu lahko definiramo tudi prijateljski razred, s čimer temu razredu omogočimo dostop do private in protected članov razreda, ki mu je prijatelj. class CKvadrat; class CPravokot { int x, y; public: int area () { return (x * y); } void Pretvori (CKvadrat a); }; class CKvadrat { private: int side; public: void set_side (int a) { side=a; } friend class CPravokot; }; void CPravokot: : Pretvori (CKvadrat a) { x = a. side; y = a. side; } int main () { CKvadrat sqr; CPravokot rect; sqr. set_side(4); rect. Pretvori(sqr); cout << rect. area(); return 0; } POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Dedovanje med razredi POMNILNIK Fizični naslovi Zelo pomembna lastnost razredov je dedovanje. Ta namreč omogoča ustvarjanje razredov, izpeljanih iz drugih že obstoječih razredov. Ti razredi si poleg svojih članov avtomatsko pridobijo tudi nekatere člane svojih “staršev”. Na primer, da želimo deklarirati več razredov, ki opisujejo geometrijske like, pravokotnik, trikotnik, itn. Vsi ti liki imajo določene skupne lastnosti, npr. oba zgoraj navedena lika lahko opišemo že z dvema daljicama: osnovo in višino. To, skupno lastnost bomo zajeli z razredom CLiki. Iz razreda CLiki pa bomo izpeljali še dva razreda: CPravokotnik in CTrikotnik, ki bosta vsebovala posebne lastnosti vsakega lika. Izpeljani razredi podedujejo vse dosegljive člane baznega razreda. Za deklaracijo izpeljanega razreda uporabljamo znak dvopičje (: ) class ime_izpeljanega: public ime_baznega_razreda { /*. . . */ }; Določilo dostopa public lahko zamenjamo tudi s katerimkoli drugim določilom dostopa, protected ali private, določa pa spodnji nivo dostopa za člane, podedovane iz baznega razreda. Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } }; POMNILNIK Fizični naslovi class CPravokotnik: public CLiki { public: int area () { return (x * y); } }; class CTrikotnik: public CLiki { public: int area () { return (x * y / 2); } }; int main () { CPravokotnik pk; CTrikotnik tk; pk. set_values (4, 5); tk. set_values (4, 5); cout << pk. area() << endl; cout << tk. area() << endl; return 0; } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Kaj vse izpeljani razred podeduje iz baznega razreda POMNILNIK Fizični naslovi protected določilo dostopa je podobno določilu private. Edina razlika med njima se nanaša ravno na dedovanje; do protected članov baznega razreda lahko dostopamo iz izpeljanega razreda do private članov pa ne. Določilo public, ki se nahaja za dvopičjem, določa minimalni nivo dostopa za vse podedovane člane, in ker je ta najmanj restriktiven, vsi podedovani člani s sabo prinesejo tudi nivoje dostopa, ki jih imajo v baznem razredu. Izpeljani razred podeduje vse člane baznega razreda razen: - konstruktorja in destruktorja - prekritih operatorjev operator=() - prijateljev Čeprav konstruktorji in destruktorji baznega razreda niso podedovani, se bosta njegov privzeti konstruktor in privzeti destruktor izvršila ob deklaraciji oz. uničenju objekta izpeljanega razreda. Če bazni razred nima privzetega konstruktorja, ali če želite, da se bo izvršil prekriti konstruktor, le-tega lahko definirate v izpeljanem razredu. Sintaksa: konstruktor_izpeljani (pars) : konstruktor_bazni (pars) {. . . } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE #include <iostream. h> class mati { public: mati () { cout << "mati: brez parametrovn"; } mati (int a) { cout << "mati: int parametern"; } }; POMNILNIK Fizični naslovi Vsebina class hci : public mati { public: hci (int a) { cout << “hci: int parameternn"; } }; class sin : public mati { public: sin (int a) : mati (a) { cout << "sin: int parameternn"; } }; int main () { hci petra (0); sin danijel (0); return 0; } mati: brez parametrov hci: int parameter mati: int parameter sin: int parameter Zaslon Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Večkratno dedovanje Definicijo dedovanja članov iz več razredov opravimo z navedbo vseh baznih razredov. Primer: class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } }; class CZaslon { public: void prikaz (int i); }; void CZaslon: : prikaz (int i) { cout << i << endl; } class CPravokotnik: public CLiki, public CZaslon { public: int area () { return (x * y); } }; class CTrikotnik: public CLiki, public CZaslon { public: int area () { return (x * y / 2); } }; int main () { CPravokotnik pk; CTrikotnik tk; pk. set_values (4, 5); tk. set_values (4, 5); pk. prikaz (pk. area()); tk. prikaz (tk. area()); return 0; } POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE POLIMORFIZEM Kazalci na bazni razred Kazalec na izpeljani razred je združljiv po tipu s kazalcem na njegov bazni razred. class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } }; class CPravokotnik: public CLiki { public: int area () { return (x * y); } }; class CTrikotnik: public CLiki { public: int area () { return (x * y / 2); } }; int main () { CPravokotnik pk; CTrikotnik tk; CLiki * k_lik 1 = &pk; CLiki * k_lik 2 = &tk; k_lik 1 ->set_values (4, 5); k_lik 2 ->set_values (4, 5); cout << pk. area() << endl; cout << tk. area() << endl; return 0; } POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Virtualni člani Virtualni član razreda je tisti, ki ga lahko v izpeljanem razredu redefiniramo. V baznem razredu ga označimo s ključno besedo virtual. Razred, ki podeduje ali v katerem je deklariran virtualni član, imenujemo polimorfni razred. class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } virtual int area () { return (0); } }; class CPravokotnik: public CLiki { public: int area () { return (x * y); } }; class CTrikotnik: public CLiki { public: int area () { return (x * y / 2); } }; int main () { CPravokotnik pk; CLiki lik; CLiki * k_lik 1 = &pk; CLiki * k_lik 2 = &lik; k_lik 1 ->set_values (4, 5); k_lik 2 ->set_values (4, 5); cout << k_lik 1 ->area() << endl; cout << k_lik 2 ->area() << endl; return 0; } POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE Abstraktni bazni razredi so zelo podobni našemu razredu CLiki iz prejšnjega primera. Edina razlika je v tem, da smo v prejšnjem primeru za objekte razreda CLiki imeli definirano funkcijo area() z minimalno funkcionalnostjo, medtem ko pa bi pri abstraktnih baznih razredih pustili funkcijo area() popolnoma brez implementacije. Namesto tega smo v deklaraciji funkcije dodali =0. Abstraktni bazni razred CLiki se bi glasil takole: class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } virtual int area () =0; }; POMNILNIK Fizični naslovi Takšen tip funkcije imenujemo čista virtualna funkcija, vse razrede, ki vsebujejo vsaj eno čisto virtualno funkcijo, pa abstraktni bazni razredi. Glavna razlika med abstraktnim baznim razredom in običajnim polimorfnim razredom je v tem, da ne moremo deklarirati objektov abstraktnega baznega razreda, ker vsaj eni njegovi funkciji manjka implementacija. Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } virtual int area (void) =0; }; POMNILNIK Fizični naslovi class CPravokotnik: public CLiki { public: int area (void) { return (x * y); } }; class CTrikotnik: public CLiki { public: int area (void) { return (x * y / 2); } }; int main () { CPravokotnik pk; CTrikotnik tk; CLiki * k_lik 1 = &pk; CLiki * k_lik 2 = &tk; k_lik 1 ->set_values (4, 5); k_lik 2 ->set_values (4, 5); cout << k_lik 1 ->area() << endl; cout << k_lik 2 ->area() << endl; return 0; } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } virtual int area (void) =0; void printarea (void) { cout << this->area() << endl; } }; POMNILNIK Fizični naslovi class CPravokotnik: public CLiki { public: int area (void) { return (x * y); } }; class CTrikotnik: public CLiki { public: int area (void) { return (x * y / 2); } }; int main () { CPravokotnik pk; CTrikotnik tk; CLiki * k_lik 1 = &pk; CLiki * k_lik 2 = &tk; k_lik 1 ->set_values (4, 5); k_lik 2 ->set_values (4, 5); k_lik 1 ->printarea(); k_lik 2 ->printarea(); return 0; } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE class CLiki { protected: int x, y; public: void set_values (int a, int b) { x = a; y = b; } virtual int area (void) =0; void printarea (void) { cout << this->area() << endl; } }; POMNILNIK Fizični naslovi class CPravokotnik: public CLiki { public: int area (void) { return (x * y); } }; class CTrikotnik: public CLiki { public: int area (void) { return (x * y / 2); } }; int main () { CLiki * k_lik 1 = new CPravokotnik; CLiki * k_lik 2 = new CTrikotnik; k_lik 1 ->set_values (4, 5); k_lik 2 ->set_values (4, 5); k_lik 1 ->printarea(); k_lik 2 ->printarea(); delete k_lik 1; delete k_lik 2; return 0; } Zaslon Vsebina Logični naslovi
UVOD V OBJEKTNO PROGRAMIRANJE ŠABLONE Šablonske funkcije so posebne funkcije, katerih koda se lahko izvaja nad različnimi podatkovnimi tipi. template <class Tip. T> Tip. T Get. Max (Tip. T a, Tip. T b) { Tip. T rezultat; rezultat = (a>b)? a : b; return (rezultat); } int main () { int i=5, j=6, k; long l=10, m=5, n; k = Get. Max<int>(i, j); n = Get. Max<long>(l, m); cout << k << endl; cout << n << endl; return 0; } Pred definicijo šablonske funkcije zapišemo ključno besedo template ter seznam formalnih argumentov šablone. S formalnimi argumenti lahko definiramo tip funkcije, tipe argumentov in tipe objektov v funkciji. POMNILNIK Fizični naslovi Zaslon Vsebina Logični naslovi
- Slides: 29