Está en la página 1de 39

BevIT: Programozs II.

2003

Bevezets az informcis technolgikba: Programozs II.


(jegyzet)

Elad: Bertk Botond

1/38

BevIT: Programozs II.

2003

Fejleszti krnyezetek: GNU C++ MS Visual C++ Watcom C++ Turbo C Borland C++

(free) (free) (conio.h nem hasznlhat; 16 bites) (conio.h nem haszhlhat)

Bevezet:
a C++ a C nyelvbl szrmazik 70-es vek Bell laboratrium, Unix opercis rendszer fejlesztse: az opercis rendszer jrarshoz j, magas szint nyelvre van szksg. A rendelkezsre ll magas szint nyelvek (COBOL, FORTRAN, PL1,) nem eredmnyeztek hatkony kdot (binris kdot) j nyelv s fordt Dennis M. Ritchie nevhez fzdik : C nyelv (Dennis M. Ritchie, Brian W. Kennighan: A C programozsi nyelv) 80-as vek kzepn kezd terjedni az objektum orientlt programozs (OOP); Bjourn Stronstup (AT&T) felismerte az objektum orientlt programozsnak, mint mdszernek a jelentsgt. Ettl kezdve a C nyelvet ilyen irnyban fejlesztik tovbb. A nyelv mai formjt ANSI ajnlsok hatrozzk meg. A C++ kicsi, strukturlt nyelv (kevesebb, mint 50 kulcsszt tartalmaz), de ezzel szemben a programnyelvek kzl a legtbb opertort tartalmazza.

A C++ nyelvi elemek:


Folyamok (streamek) hasznlata; Elre definilt tpus #include <iostream.h> //Borland & Turbo C esetn stream.h int main (){ int n; cout<<Enter an integer:; cin>>n; cout<<The value:<<n<<\n; //Egyszeren jabb elemet fzhetnk hozz return 0; } Konstansok s konstans paramterek szintaxis: const tpus vltoz[=rtk] const double PI=3.1415926536; A const vltoz rtkt nem vltoztathatjuk meg; elnye, hogy ismeri a fordt a tpust (definenal ellenttben). Logikai tpus (ANSI C++ 96-tl) // a vltoz lehetsges rtkei: true, false 2/38

Szintaxisa: bool vltoz

BevIT: Programozs II.

2003

#include <iostream.h>

//cin s cout miatt

bool Prime(const int n){ int i; if (n<2) return false; for (i=2;i*i<=n;i++) if (n%i==0) return false; return true; } int main (){ int n; cout<<Enter an integer:; cin>>n; if (Prime(n)) cout<<Prime.\n; else cout<<Non prime.\n; return 0; } Azonos nev fggvnyek tbbfle paramterrel vagy argumentummal #include <iostream.h> int Abs(const int i){ return i<0?-i:i; } double Abs(const double d){ return d<0.0?-d:d; } int main(){ int n; double f; cout<<Enter an integer number:; cin>>n; cout<<Enter a real number:; cin>>f; cout<<The absolute value of the integer: <<Abs(n)<<\n; cout<<The absolute value of the real number: <<Abs(f)<<\n; return 0; } Az azonos nev fggvnyek kzl hogyan vlaszt a fordt: az argumentumok szma: hvhat-e a fggvny adott szm paramterrel? 3/38 //const mert i rtkt nem akarjuk megvltoztatni

BevIT: Programozs II.

2003

az argumentumok tpusa: kevesebb tpuskonverzira van-e szksg, mint ms, azonos nev fggvny hvsa esetn

Az elz plda alapjn: 1. felttel alapjn nem lehet eldnteni, mert ugyan annyi az argumentum 2. felttel alapjn hajtdik vgre a program

Alaprtelmezett argumentumrtk
C++-ban egy fggvny argumentumban szerepl vltozknak adhatunk alaprtelmezett (default) rtket, Fggvny deklarcijban inicializlt argumentum (default rtkkel rendelkez) paramter utn csak inicializlt paramter kvetkezhet (pl.: (int b, int c, int a=1,...) Ha egy fggvnynek n db argumentuma van, s ebbl m db-nak alaprtelmezett (default) rtke, akkor a fggvny meghvhat n-m db, n-m+1,...,n szm paramterrel. Teht legalbb a nem inicializltakat meg kell adni! Pl.: #include <iostrem.h> void test (int a, int b=2, int c=3){ cout<<a<<b<<c; } int main( ){ test(1); // 1 2 3 fog kirdni test(2,1) // 2 1 3 fog kirdni test(3,2,1) // 3 2 1 fog kirdni return 0; } A new s delete opertorok, 0 mutat new = memriafoglals Szintaxisa: mutat_neve = new tpus Pl.: int *p; p=new int[10] //10 egszet tartalmaz tmb cmnek lefoglalsa

0 mutat = a pointerhez nem tartozik memriacm: sehova sem mutat mutat. Ha egy mutat rtke 0, akkor nem trterletre mutat, hanem azt jelzi, hogy nem foglaltunk hozz memrit. delete : memria felszabadtsa szintaxisa: delete mutat_neve; Pl.: delete p; Cm szerinti paramtertads

Szintaxisa: tpus & vltoz Pl.: int & i; 4/38

BevIT: Programozs II.

2003

Pldaprogram: #include <iostream.h> void GetInt(int &n,const int lb=0,const int ub=100) //adott intervallumba es szm bekrse { bool ok; do{ cin>>n; if (n<lb) cout<<"The required integer value must be greater or equal to "<<lb<<"."; if (n>ub) cout<<"The required integer value must be less or equal to "<<ub<<"."; ok = (n>=lb && n<=ub); if (!ok) cout <<"\nRe-enter the value please: "; }while (!ok); } void GetNumbers(int* &t,int &num) //egy egsz tpus tmb bekrse { int i; cout<<"Enter the number of the values: "; GetInt(num,1,10); if (t) delete t; //ha t=0, vagyis hamis, akkor trlje t=new double[num]; for (i=0;i<num;i++){ cout<<"Enter the "<<i+1<<". value: "; cin>>t[i]; } } void PutNumbers(const int* t,const int num) //A const hasznlata (Paramter) Vltozk : o const int i; : i tartalma nem vltoztathat o const int *a; : az a mutat ltal mutatott trterlet pl.: tmb nem vltoztathat o int *const a; : az a mutat nem vltoztathat meg o const int *const b; : sem a b mutat, sem az ltala mutatott trterlet nem vltoztathat meg { int i; for (i=0;i<num;i++)

5/38

BevIT: Programozs II. cout<<"The "<<i+1<<". value: "<<t[i]<<"\n"; } double Min(const int* t,const int num) //tmb minimlis elemnek kivlasztsa { int i; int min=t[0]; //inicializls az 1. elemmel for(i=1;i<num;i++) if (t[i]<min) min=t[i]; return min; } double Avg(const int* t,const int num) //a tmb tlagnak meghatrozsa { int i; double sum=t[0]; for(i=1;i<num;i++) sum += t[i]; return sum/double(num); }

2003

int main( ){ int *a=0; int n; GetNumbers(a,n); PutNumbers(a,n); cout<<The smallest number is: <<min(a,n)<<\n; cout<<The average of the array is: <<Avg(a,n)<<\n; if(a) delete a; return 0; }

Paramtervltozk a memriban:
rtk szerint tadott paramtervltoz: az tadott vltoz tartalma lemsoldik egy msik trterletre void test1(int b){ b=3; } //2.2. int main(){ int a=1; test1(a); return 0; } //2.1.

//1. //2. //3.

6/38

BevIT: Programozs II. 1. | 2.1. 2.2. 3. a ___________________ | 0 | 0 0 0 0 0 0 2 Cm: E0000001 //2.1. //2.2. //1. //2. //3. 0 0 0 0 0 0 0 2 Cm: E0000001 0 0 0 0 0 0 0 2 Cm: E0000001 a __________________ 0 | 0 0 0 0 0 0 2 Cm: E0000001 b ___________________

2003

| | 0 0 0 0 0 0 0 2 b ___________________ | | 0 0 0 0 0 0 0 3

Vltoz rtk szerint tadott cme: void test2(int *p){ *p=3; } int main(){ int a=1; test2(&a); return 0; } 1. a ___________________ | | 0 0 0 0 0 0 0 1 Cm: E0000001 *p ___________________ | 0 0 0 0 0 0 0 1 Cm: E0000001 |

p ___________________ | | E 0 0 0 0 0 0 1

2.1.

7/38

BevIT: Programozs II. 2.2. | 0 0 0 0 0 0 0 3 Cm: E0000001 *p ___________________ | P ___________________

2003

| | E 0 0 0 0 0 0 1

3. a ___________________ | 0 | 0 0 0 0 0 0 3 E0000001

Cm-szerinti paramtertads vagy referencia tpus paramter esetn egy j nvvel, az eredeti trterletre hivatkozunk void test3(int &b){ b=3; } int main(){ int a=1; test3(a); return 0; } 1. a ___________________ 2.1. b ___________________ 2.2. b ___________________ 3. a ___________________ | 0 | 0 0 0 0 0 0 3 Cm: E0000001 | 0 | 0 0 0 0 0 0 3 Cm: E0000001 | 0 | 0 0 0 0 0 0 1 Cm: E0000001 | 0 | 0 0 0 0 0 0 1 Cm: E0000001 //2.1. //2.2. //1. //2. //3.

8/38

BevIT: Programozs II.

2003

Mikor melyiket hasznljuk?


Paramtertads optimalizlsa: 1. Vltozik a paramtervltoz rtke 1.1. Az tadott vltoz rtkt szeretnnk megrizni: rtk szerinti paramtertads (1. eset) 1.2. Vissza szeretnnk kapni a megvltozott rtket: cm szerinti paramtertads (3. eset) 2. A paramtervltoz rtke nem vltozik 2.1. vltoz mrete <= a cmnek mretnl : rtk szerint tadott konstans paramter Pl.: (const int b); 2.2. vltoz mrete > a cmnek mretnl: cm szerinti tads konstans paramterbe vagy konstans referencia Pl.: (const string &s); Megjegyzs: jobbrtk (rvalue) cm szerint csak konstans paramterben adhat t. Pl.: void Print( const string &s){ } Print(string(123b)+s1+\n+...); Akkor rdemes a cmet tadni, ha a cm kisebb helyet foglal, mint a vltoz rtke (pl. stringek).

Hogyan mkdik a fordt:


Forrskdok Trgykdok (object) (source code) fordts *.obj ; *.o *.c ; *.h Fggvnyknyvtrak(library) *.cpp ; *.hpp compeling *.lib ; *.a (platform fggetlenek) (CPU fgg)
sszekapcsols linking

Futtathat llomnyok (Executable) Dinamikus knyvtrak (Dynamic link libraries) *.exe, *.dll (Op. rendszer fgg)

1.h 1.cpp ->1.obj 2.h 2.cpp -> 2. obj 3.h 3.cpp -> 3.obj

12.lib 123.exe (pontosan egy cpp-ben szerepeljen main fggvny)

OBJEKTUM-ORIENTLT PROGRAMOZS (OOP)


(Object-oriented programming) Kzelti a termszetes gondolkodst: - bizonyos kijelentsek/megfogalmazsok csak adott kontextusban rtelmesek - eszkzhasznlat annak bels szerkezett nem ismerve Mi az OOP? Az OOP nem programozs (kdols), hanem programtervezsi, szervezsi mdszertan. A programok szervezsrl szl: szervezzk a programjainkat objektumok kr. Az objektum

9/38

BevIT: Programozs II.

2003

llapotvltozk + viselkedsek. A viselkedsek olyan mveletek, amelyek hozzfrnek az llapotokhoz, vagy megvltoztathatjk azokat. Egysgbezrs (encapsulation) Az OOP tmogatja az egysgbezrst. Az egyetlen md egy objektum llapotnak megvltoztatsra sajt mveletein keresztl. Egy objektum belseje (llapotok) a klvilg szmra rejtett. Nincs olyan OOP nyelv, mely az egysgbezrst ne tmogatn. Az egysgbezrs hogyan vltoztatja meg a szoftverfejlesztst? - a kapcsold felletek tervezsvel kell tbb idt tlteni prbljuk a felletet minl pontosabban meghatrozni a fellet megvltoztatsa fjdalmas - a szoftver letciklusa talakul a korbbi programozsi feladatokhoz kpest A szoftverfejleszts egyes fzisaira fordtott id szzalkban hagyomnyos s OO programozsi mdszerrel. Hagyomnyos 30-40% 35-45% 15-20% OOP 70% 20% 10%

Tervezs Kdols s hibakeress Tesztels

Az egysgbezrs elnyei: Knny karbantarthatsg: nincsenek bels sszefggsek a kdrszek kztt Plug & Play: azonos viselkeds objektumok egymssal helyettesthetk (klnbz implementci) Knnyebb rthetsg: csak a felletet kell rteni Gyors fejleszts: egyszer megvalsts ksbb kifinomultabbra cserlhet; csak az objektum belsejben kell vltoztatni Modulris ptkezs: minden objektum egy modul, ami a tbbitl fggetlenl fejleszthet/tesztelhet Megjegyzs: az OOP hrom legfontosabb jellemzje: - egysgbezrs - rkls/szrmaztats - tbbalaksg / poliformizmus Ezen lehetsgeket a ksbbiekben ebben a sorrendben trgyaljuk. Osztlyok s objektumok Analgia: tpus -> vltoz osztly -> objektum osztly : sszetett adatszerkezet a hozz kapcsold mveletekkel egytt objektum : egy konkrt pldny az adott tpuson bell Osztly deklarcija Szintaxis: class osztlynv{ Adattagok; 10/38

BevIT: Programozs II. Mveletek (fggvnyek formjban); }; Objektum deklarcija Szintaxis: osztlynv objektumnv; Dinamikusan: osztlynv *objektummutat; Objektummutat = new osztlynv; Objektum trlse = delete objektummutat; Pl.: class class1{ }; int main(){ class1 obj,*pobj; pobj=new class1; delete pobj; return 0; }

2003

//*pobj dinamikus objektum

Osztly metdus: class store{ int s; public: int GetStire() const(); Ha egy metdus konstans tpus akkor az osztlyban trolt adattagokat nem vltoztatja meg. Konstans objektumoknak csak konstans tpus metdusai hvhatak. //

Egysgbezrs: Hozzfrsi jogosultsgok mdostsval adatok s eljrsok/fggvnyek (metdusok) egy rsze a klvilg szmra nem hozzfrhet (private) ms rsze nyilvnos (public). Alaprtelmezs szerint minden private. Pl.: class cl1{ private: int state; public: void SetState(const int i); int GetState(); }; Pl.: void cl1::SetState(const int i){ state=i; } int cl1::GetState(){ 11/38

BevIT: Programozs II.

2003

return state; } int main(){ cl1 o; int j; o.SetState(10); //o.state=10;<-srti a jogosultsgot j=o.GetState(); return 0; } Konstruktor s destruktor: 1. Konstruktor 1.1. Olyan tagfggvny, melynek neve megegyezik az osztlyval 1.2. Nem rendelkezik visszatrsi rtkkel 1.3. Akkor indul el az eljrs, amikor az osztlyba tartoz objektum ltrejn 1.4. Feladata az llapotvltozk inicializlsa ( !dinamikus vltozk, adatszerkezetek) 2. Destruktor 2.1. Olyan tagfggvny melynek neve: ~osztlynv 2.2. Nincs visszatrsi rtke 2.3. Akkor indul el, amikor egy, az osztlyba tartoz objektum megsznik 2.4. Feladata az osztlyban trolt dinamikus adatszerkezetek trlse. Pl.: class cl2{ public: cl2(); ~cl2(); }; cl2::cl2(){}; cl2::~cl2(){}; int main(){ cl2 o,*po; po=new cl2; delete po; return 0; } //o.cl2() lefut //po->cl2() //po->~cl2() //o.~cl2() lefut

Paramterezett s alaprtelmezett (default) konstruktorok


A konstruktoroknak ms metdusokhoz hasonlan lehetnek argumentumaik. Ekkor paramterezett konstruktorrl beszlnk. Ha egy konstruktornak nincs argumentuma, akkor alaprtelmezett konstruktorrl beszlnk. A konstruktor argumentumait egy objektum ltrehozsakor adhatjuk meg.

Szintaxis: <osztlynv> <objektumnv> (konstr. paramterei) vagy Objektummutat = new osztly_nv (konstr. Paramterei) 12/38

BevIT: Programozs II.

2003

Ha egy objektum ltrehozsakor nem adunk meg paramtereket a konstruktor szmra, akkor a default konstruktor indul el.

Tipikus plda: objektumtmb ltrehozsa Szintaxis: <osztlynv> <osztlytmb>[objektumok_szma] Ekkor a tmb minden elemre a default konstruktor hvdik meg. Pl.: #include <iostrem.h> class cl2{ private: int state; public: cl2(){state=0;}; cl2(const int pstate) {state = pstate ;}; //e kt sor helyett rhat a kv.: (const int pstate=0){state=pstate;};// int GetState(){return state;}; }; int main(){ cl2 a,*b,*c; //a.cl2() a.state = 0 cl2 d(2); //d.cl2(2) d.state = 2 b=new cl2; //b->cl2() b->state = 0 c=new cl2(3); //c->cl2(3) c->state = 3 cout<<a.GetState()<<b->GetState()<<c->GetState() <<d.GetState; // 0 0 3 2 r ki delete b; delete c; return 0; }

Begyazott fggvnyek (inline functions)


Amennyiben egy metdus trzst belerjuk az osztly deklarcijba, akkor ezt a metdust a fordt begyazott fggvnyknt fogja kezelni. Begyazott fggvny esetn nincs paramtertads s fggvny hvs, hanem a fordt a begyazott fggvny trzst bemsolja a hvs helyre. Begyazott fggvny deklarcijnak szintaxisa: inline <fv_deklarcija>

Gyakran hasznlt kdrszletek hatkony megvalstsa


Fggvnyrs: int Abs(const int i){ return i<0?-i:i;} Begyazott fggvny: inline int Abs(const int i){ return i<0?-i:i;}

13/38

BevIT: Programozs II. // be fogja msolni a hvs helyre: b=Abs(b); esetn i=b; b=(i<0?-i:i); elnye: nincs fggvnyhvshoz kapcsold adminisztrci, teht gyorsabb htrnya: sokszor hvjuk meg -> sok helyre msoldik -> n a kd mrete Makr hasznlata: #define Abs(x)(x<0?-x:x) y=Abs(y); z=Abs(z++); //y=(y<0?-y:y); //z=(z++<0?-z++:z++);

2003

Itt a z rtke nem 1-gyel vltozik! elnye: gyors htrnya: nem vrt eredmnnyel szolglhat

Dinamikus adatszerkezetek : verem


Mveletek: push: egy elem beraksa a verembe pop: egy elem kivtele a verembl A vermet, mint adatszerkezetet LIFO-nak is hvjk (Last In First Out). Amit utoljra tettnk a verembe, azt vehetjk ki elszr. Plda:

5 push 2 push 5 pop push 6 push 8

a=8 pop a

b=6 pop b

a=2 pop a

5 2

6 2

8 6 2

6 2

268

befel

->

8 6 2 kifel

A verem megfordtja a benne trolt adatok sorrendjt. Verem megvalstsa dinamikus tmbben trolva. //stack1.h #ifndef _STACK_H #define _STACK_H const int DEFAULT_STACK_SIZE=5; class stack{ private: int maxelemnum,elemnum,*store; 14/38

BevIT: Programozs II. bool Full(); public: stack(int pmaxelemnum=DEFAULT_STACK_SIZE); bool Empty(); bool Push(const int n); bool Pop(int &n); ~stack(); }; #endif // _STACK_H //stack1.cpp #include stack1.h #include <iostream.h> stack::stack(int pmaxelemnum){ maxelemnum=pmaxelemnum; store=new int[maxelemnum]; elemnum=0; } bool stack::Full(){ return elemnum==maxelemnum; } bool stack::Empty(){ return elemnum==0; } bool stack::Push(const int n){ if (Full()) return false; store[elemnum++]=n; return true; } bool stack::Pop(int &n){ if (Empty()) return false; n=store[--elemnum]; return true; } stack::~stack(){ delete store; } int main() { //a fprogram stack *s=new stack; char c; int n; do{ cout<<(P)ush\n(P)op\n(E)xit\n;

2003

15/38

BevIT: Programozs II. cout<<Enter your selection : ; cin>>c; if(c==p){ cout<<Enter a number:; cin>>n; if(s->Push(n)) cout<<OK!\n); } if(c==o){ if(s->Pop(n)) cout<<n<<\n;} else cout<<Empty stack.\n; }while (c!=e); delete s; return 0; } Verem megvalstsa dinamikusan lncolt listval 2 5 8 X

2003

Stack_elem*

Elem + kv. cme (next)

int

stack_elem*

NULL pointer

//stack2.h #ifndef _STACK2_H #define _STACK2_H struct stack_elem{ int n; stack_elem *next; }; class stack{ protected: stack_elem *top; public: stack(); bool Empty(); bool Push(const int n); bool Pop(int &n); ~stack(); }; #endif _STACK_H //stack2.cpp #include stack2.h stack::stack(){ top=0; } bool stack::Empty(){ return top==0; } 16/38

BevIT: Programozs II. bool stack::Push(const int n){ stack_elem *new_elem=new stack_elem; if (new_elem==0) return false; new_elem->n=n; new_elem->next=top; top=new_elem; return true; } 5 top Push(3) //1 new_elem //2 3 new_elem //3
3

2003

//1 //2 //3 //4

ltrejn

beleteszi a hrmat

new_elem
top 5

Mutasson oda, ahova a top


2 X

//4 3 5 2 X

top

bool stack::Pop(int &n){ stack_elem * to_delete; if (Empty()) return false; to_delete=top; n=to_delete->n; top=to_delete->next; delete to_delete; return true; }

//1 //2 //3 //4

17/38

BevIT: Programozs II. 5 top 2 X

2003

18/38

BevIT: Programozs II. Pop(n) //1 to_delete

2003

top //2 //3 n=5

5 to_delete top

//4 to_delete X

top

2 //destruktor

stack::~stack(){ stack_elem * to_delete; while (top!=0){ to_delete=top; top=to_delete->next; delete to_delete; } }

Szrmaztats s rkls
OOP tulajdonsgai: - egysgbezrs - szrmaztats, rkls - poliformizmus fogalma: a szrmaztats az az eljrs, melynek eredmnyeknt egy osztlybl egy msik osztlyt kapunk, mikzben annak (az snek) nhny tulajdonsgt megtartjuk (rktjk) a leszrmaztatott (gyermek) osztlyba, msokat megvltoztatunk s kiegsztnk. sosztly > szrmaztats -> szrmaztatott (gyermek) osztly A gyermek az s tulajdonsgait rkli, de ezek nhetnek, cskkenhetnek s vltozhatnak is. 19/38

BevIT: Programozs II. Hozzfrsi jogosultsgok: o private: protected: public:

2003

csak az osztlyon bell hozzfrhetek (legszigorbb) az osztlyban s szrmaztatott osztlyaiban (gyermekeiben) hozzfrhetek tetszlegesen hozzfrhet

Hozzfrs mdostsa szrmaztats sorn:


szrmaztats tpusa hozzfrs az sben

Private

Protected

Public private protected public

private NEM private protected Hozzprotected public frhet protected A szrmaztats csak szigorthatja a hozzfrs szabjait! Pl.: //stack3.h #ifndef _STACK3_H #define _STACK3_H #include stack2.h class adv_stack:public stack{ public: bool Top(int &n); }; #endif //stack3.cpp bool adv_stack::Top(int &n){ if (Empty()) return false; n=top->n; return true; } Osztlydiagram adv_stack
top Push Pop Empty Top Szrmaztats: public

stack
top Push Pop Empty

jelli a megvalsts helyt

Polimorfizmus (tbbalaksg/tbbarcsg):
Metdus tdefinils (method overloading): Ha a szrmaztatott osztlyban definilunk s megvalstottunk azonos nev s argumentum metdust, mint amilyen nev s paramter az sben volt, akkor:

20/38

BevIT: Programozs II.

2003

a) A szrmaztatott osztlyban s annak leszrmaztatott osztlyaiban, metdusaiban az tdefinilt metdus nevvel a szrmaztatott osztlybeli metdushoz frnk hozz. b) Az sosztly metdusaiban vltozatlanul az s osztlybeli metdushoz frnk hozz. Pl.: #include <iostream.h> class clA{ private: void fv1(){cout<<clA::fv1\n;}; public void fv2(){cout<<clA::fv2\n;}; void fv3(){cout<<clA::fv3\n;}; }; class clB:public clA{ public: void fv1(){cout<<clB::fv1\n;}; void fv2(){cout<<clB::fv2\n;}; }; int main(){ clA a,*pa; clB b,*pb; a.fv2(); a.fv3(); pa=&a pa->fv2(); pa->fv3(); b.fv1(); b.fv2(); b.fv3(); pb=&b; pb->fv1(); pb->fv2(); pb->fv3(); pa=&b pa->fv1(); pa->fv2(); pa->fv3(); clB a Fv1 Fv2 Fv3

//a.fv1 nem frhet hozz //clA::fv2 mert private //clA::fv3 //pa->fv1(); nem hajthat vgre mert private //clA::fv2 //clA::fv3 //clB::fv1 //clB::fv2 //clA::fv3 //clB::fv1 //clB::fv2 //clA::fv3 //nem hajthat vgre //clA::fv2 //clA::fv3 clA Fv1 Fv2 Fv3

Szrm.: public

b 21/38

BevIT: Programozs II.

2003

clB pb=&b

Fv1 Fv2 Fv3

pa=&b b

clA Fv1 Fv2 Fv3

Megjegyzs: sosztlyra mutat pointer megkaphatja egy szrmaztatott osztlybeli objektum cmt, de csak azokhoz a metdusokhoz frnk hozz e pointeren keresztl, melyek az s osztlyban definiltak.

Virtulis metdusok:
Ha a szrmaztatott osztlyban definilunk s megvalstunk azonos nev s argumentum virtulis metdust, mint amilyen nev s argumentum az sben ltezett, akkor : - a szrmaztatott osztly metdusaiban, - annak leszrmazottaiban s az sosztlytl rklt metdusokban is az tdefinilt metdus nevvel a szrmaztatottbeli vltozatot rjk el. Pl.: #include <iostream.h> class clA{ private: void fv1(){cout<<clA::fv1\n;}; public: virtual void fv2(){cout<<clA::fv2\n;}; void fv3(){cout<<clA::fv3\n;fv2();}; }; class clB:public clA{ public: void fv1(){cout<<clB::fv1\n;}; virtual void fv2(){cout<<clB::fv2\n;}; }; int main(){ clA a,*pa; clB b,*pb; a.fv2(); a.fv3(); pa=&a; pa->fv2(); pa->fv3(); b.fv1(); b.fv2(); b.fv3(); pb=&b; pb->fv1(); pb->fv2(); pb->fv3();

//a.fv1() nem rhet el(private) //clA::fv2 //clA::fv3 //pa->fv1()nem rhet el(private) //clA::fv2 //clA::fv3 //clB::fv1 //clB::fv2 //clA::fv3 clB::fv2 // clB::fv1 // clB::fv2 // clA::fv3

clB::fv2 22/38

BevIT: Programozs II. pa=&b; pa->fv2(); pa->fv3(); return 0; } clA v. clB v. pb b Ktfle szmol eljrs kzs ssel s mdostott (tdefinilt) metdussal: // calc.cpp #include <iostream.h> class calc{ protected: double a,b; double Get(); virtual double Result(); public: void GetInput(); void PutResult(); }; double calc::Get(){ double d; cout<<"Enter a number: "; cin>>d; return d; } void calc::GetInput(){ a=Get(); b=Get(); } void calc::PutResult(){ cout<<"The result is: "<<Result()<<'\n'; } double calc::Result(){ return 0.0; fv1 fv2 fv3 virtualits miatt fv1 fv2 fv3

2003 //pa->fv1()nem rhet el(private) //clB::fv2 //clA::fv3 clB::fv2

virtulis fv. meghvja

clA v. pa=&b

fv1 fv2 fv3

23/38

BevIT: Programozs II. } class add_calc:public calc{ virtual double Result(); }; double add_calc::Result(){ return a+b; } class sub_calc:public calc{ virtual double Result(); }; double sub_calc::Result(){ return a-b; } int main(){ calc *c0; char c; do{ cout<<"(s)um\n(d)ifference\nEnter your selection: "; cin>>c; }while (c!='s' && c!='d'); if (c=='s') c0=new add_calc; else c0=new sub_calc; c0->GetInput(); c0->PutResult(); delete c0; return 0; } add_calc Get GetInput PutResult Result Szrm: public Virtulis metdusok calc (s) Get GetInput PutResult v. Result

2003

meghvs

v.

c0: erre hivatkozunk, de ez hvdik meg

Binris keresfa
Binris fa: krmentes, irnytott (erd), sszefgg grf fa. A cscsok Kifoka (kiindul lek szma) legfeljebb kett, ezrt binris.

24/38

BevIT: Programozs II. Plda: gykr gykrhez tartoz bal oldali rszgrf

2003

levelek

Amelyik cscs befoka nulla, azt gykrnek, amelyik cscs kifoka nulla, azt levlnek nevezzk. Binris fban egy cscsbl kiindul kt let bal s jobb gnak nevezzk. Egy cscshoz a bal (jobb) gn kapcsold sszefgg rszgrfot bal (jobb) oldali rszgrfnak nevezzk. Fa bejrsi algoritmusok: PreOrder : kzp(cscs), bal(g), jobb(g) InOrder : bal(g), kzp(cscs), jobb(g) PostOrder: bal(g), Jobb(g), kzp(cscs) 1 2 4 5 3 6 7 Bejrsa: PreOrder: InOrder: PostOrder: 1-2-4-3-5-6-7 4-2-1-5-3-6-7 4-2-5-7-6-3-1

Binris keresfa: dinamikus adatszerkezet a trolt adatokon rendezst feltteleznk egy cscshoz tartoz bal oldali rszgrfban a rendezs szerint csak nla kisebb vagy egyenl cscsok vannak egy cscshoz tartoz jobb oldali rszgrfban csak nla nagyobb elemek vannak (a rendezs szerint)

25/38

BevIT: Programozs II. Plda.: binris keresfa felptse a 4,9,7,6,2,8,10,10 szmok trolsra
4 2 7 6 8 10 9 10

2003

InOrder bejrssal kiolvasva :2,4,6,7,8,9,10,10 Binris keresfa felptse: elemek egyenknti beszrsval: Eljrs Beszr (fa, elem); Ha a fa nem ltezik, akkor a fa=elemet tartalmaz egyetlen cscs; Klnben Ha fa.gykr >= elem, akkor beszr (fa.balg, elem); Klnben Beszr (fa.jobbg, elem); Eljrs vge; Fa lebontsa PostOrder eljrssal ( a cscsot tntetjk el utoljra). Eljrs lebont (fa); Ha ltezik fa.balg, akkor lebont (fa.balg); Ha ltezik fa.jobbg, akkor lebont (fa.jobbg); Trl fa; Eljrs vge; Mirt hatkony adatszerkezet? Egy cscs megtallsa legfeljebb pr lpsben trtnik, ahol a m a binris magassg. A binris keresfban egy elem megtallshoz szksges lpsszm = l 0<= l <=m A binris fa magassga: log2 n <= m <= n-1 ahol n az elemek szma (cscsok szma) legjobb eset: 0<= l <= log2 n legrosszabb eset: 0<= l <= n-1 vrhat rtkben: l log2n Rendezs binris keresfval: Bemenet : elemek sorozata Kimenet : elemek rendezett sorozata Lps : a) elemek beraksa binris keresfba b) elemek kiolvassa InOrder eljrssal

26/38

BevIT: Programozs II. Rendezs binris keresfval: (C++ megvalstsa) //Binary Tree Sort #include <iostream.h> class tree{ private: int key; tree *less,*greater; public: tree(const int i); void Insert(const int i); void GetContent(int* t,int &c); ~tree(); }; tree::tree(const int i){ key=i; less=0; greater=0; } void TreeInsert(tree* &t,const int i){ if (t) t->Insert(i); //ha ltezik a fa beszrja i-t else t=new tree(i); //klnben ltrehozza } tree::~tree(){ if (less) delete less; if (greater) delete greater; } void tree::Insert(const int i){ if (i<=key) TreeInsert(less,i); else TreeInsert(greater,i); } void tree::GetContent(int* t,int &c){ if (less) less->GetContent(t,c); t[c++]=key; if (greater) greater->GetContent(t,c); } int main(){ int i,*out,c=0; char ch; tree* t=0; do{ cout<<"Enter the number: "; cin>>i;

2003

27/38

BevIT: Programozs II.

2003

c++; TreeInsert(t,i); do{ cout<<"Is there any other number ? (y/n): "; cin>>ch; }while (ch!='y' && ch!='n'); }while (ch!='n'); out=new int[c]; c=0; t->GetContent(out,c); cout<<"Numbers in decreasing order:\n"; while (c) cout<<out[--c]<<' '; delete t; return 0; } Lpsek: (plda) 0) t=0 1) az 5 szm beszrsa tree* key=5 less=0 2) a 2 szm beszrsa: greater=0

key less key=2 less=0 greater=0 greater=0

tree; out[1]=5, c=2

out[0]=2; c=1

3) szmok kiolvassa: b) lps t-> GetContent: meghvja a: a) t->less->GetContent, out[0]=2, c=1 out[1]=5, c=2 4) szmok kirsa: out[1]->5 out[0]->2 Msol konstruktor (copy constructor): A msol konstruktor pontosan egy argumentummal rendelkezik, amely argumentum tpusa az adott osztlyba tartoz objektumra hivatkoz referencia tpus, ltalban konstans.

28/38

BevIT: Programozs II. Pl.: class sx( sx(const sx &psx);

2003

Feladata: a paramterknt kapott objektummal azonos tartalm pldnyt (objektumot) hozzon ltre. Pl.: sx sx1(), sx2(sx1),*sx3; sx3=new sx(sx1); Mikor van szksg msol konstruktorra: rtk szerinti paramter tads sorn vltoz/objektum msolatt a fordt a msol konstruktor segtsgvel kszti el. Pl.: void StrLen(const string s) fggvny hvsakor a string::string(const string&); konstruktor hvdik meg. rtk szerinti visszatrsi rtk esetn: Pl.: string UpperCase(const string &s){ string s1; : return s1;} //e sor hatsra is a string::string(const string&) msol konstruktor hvdik meg.

Cm szerinti (hivatkozs tpus) visszatrsi rtk A referencin keresztl kzvetlenl azt a vltozt adja vissza, mely a return utn szerepel. FONTOS! Ez a vltoz nem lehet az eljrs loklis vltozja. Pl.: class store{ private: int s; public: int &GetState(){return s;}; Ekkor a msol konstruktor nem hajtdik vgre. Alaprtelmezett msol konstruktor(cc): He egy osztlyban a msol konstruktor nem definilt, akkor a fordt alaprtelmezett msol konstruktort generl, mely az osztlyban trolt minden statikus adattagot lemsol. Kvetkezmny: dinamikus adatszerkezeteket tartalmaz objektumok msolsra az alaprtelmezett (default) msol konstruktor nem alkalmas, teht a dinamikus adatszerkezeteket tartalmaz osztly msol konstruktort mindig definilni kell.

29/38

BevIT: Programozs II. Pl.: class store{ int state : }; : store s1(2),s2(s1) s1 state=2 store Pl.: def. konstr. s2 state=2 store

2003

class stack{ top* stack_elem; : }; stack st1; st1.valami; stack st2(st1); st1 Top E0120001 stack X st2 Top E0120001 stack

Itt hiba van! Ha az osztly dinamikus adatszerkezetet tartalmaz, akkor az alaprtelmezett msol konstruktor csak a mutatkat msolja le, melyek gy azonos trterletre mutatnak, teht ha az egyik adatszerkezet megvltozik vagy megsznik, akkor a msik is. Fontos!: ha egy osztly dinamikus adatszerkezeteket tartalmaz, akkor meg kell rni a msol konstruktort, ami azt tmsolja. Pl.: ltrehozza a verem elemeit tartalmaz lncolt lista egy jabb megvalsulst, ami a lemsolttal azonos adatokat tartalmaz.

Opertorok
Pl.: a+b ltalban van visszatrsi rtke mindig van legalbb egy argumentuma hvsa s deklarcija a fggvnyektl szintaktikjban klnbzik. // + opertor kt argumentuma van: a kt sszeadand szm van visszatrsi rtk: a kt szm sszege a + opertor jellemzen nem vltoztatja meg az argumentumait, vagyis argumentumai konstans paramterek.

30/38

BevIT: Programozs II. Pl.: a=b Pl.: //rtkads opertor kt argumentuma van, jellemzen a jobb oldali (msodik) nem vltozik (konstans), a bal oldali (els) vltozik (referencia tpus) visszatrsi rtke is jellemzen a msodik argumentum rtke

2003

a= =b //logikai egyenlsg opertor - jellemzen kett konstans argumentuma van - jellemzen logikai visszatrsi rtk

Opertorok definilsa fggvnyknt: Szintaxis: <vissz.rt. tpusa> operator <op.jele> (argumentumok) Pl.: cl operator=(cl &a,cl b); cl operator+(const cl &a, const cl &b); bool operator==(const cl &a, const cl &b); Megjegyzs: az opertorok argumentumainak tpusait tetszlegesen vlaszthatjuk, de az argumentumok szma nem trhet el a nyelvre szoksostl. Pl.: = op.: 2 argumentum + op.: 2 argumentum ! op.: 1 argumentum ? op.: 3 argumentum j fle opertort nem lehet ltrehozni, csak tdefinilni a mr meglvket. Opertor definilsa osztly metdusaknt: Ekkor az opertort az els argumentumnak tagfggvnyeknt rtelmezzk. Pl.: class clx{ public: clx operator=(const clx &b); clx operator+(const clx &b) const; bool operator==(const clx &b) const; }; clx a,b,c; a=b; c=a+b; //a.operator = (b); hvdik //c.operator = (a.operator+(b)); hvdik

Karaktersorozatot dinamikus tmbben trol string osztly = s + opertorokkal


//str2.h #ifndef _STR_H #define _STR_H #include <iostream.h> class string{ private: char* store; 31/38

BevIT: Programozs II. int len; void Init(); void New(const int plen); void Delete(); public: string(); ~string(); string& operator=(const char c); string& operator=(const char* pstore); string& operator=(const string& s); string(const char c); string(const char *pstore); string(const string &s); string operator+(const string& s)const; int Len()const{return len;}; void CopyCharsTo(char* const s, const int maxlen)const; }; int StrLen(const char *pstore); inline int StrLen(const string &s); ostream& operator<<(ostream &o,const string &s); #endif // _STR_H //str2.cpp #include <memory.h> #include "str2.h" int StrLen(const char *pstore){ int len=0; while (pstore[len]) len++; return len; } inline int StrLen(const string &s){ return s.Len(); } void string::Init(){ len=0; store=0; } void string::New(const int plen){ Delete(); len=plen; store=new char[len]; } void string::Delete(){ if (store) delete store;

2003

32/38

BevIT: Programozs II. } string::string(){ Init(); } string::~string(){ Delete(); } string& string::operator=(const char c){ New(1); store[0]=c; return *this; } string& string::operator=(const char* pstore){ New(StrLen(pstore)); memcpy(store,pstore,len); return *this; } string& string::operator=(const string& s){ New(StrLen(s)); memcpy(store,s.store,len); return *this; } string::string(const char c){ Init(); *this=c; } string::string(const char *pstore){ Init(); *this=pstore; } string::string(const string& s){ Init(); *this=s; } string string::operator+(const string& s)const{ string s2; s2.New(len+s.len); if (len) memcpy(s2.store,store,len); if (s.len) memcpy(s2.store+len,s.store,s.len); return s2; } void string::CopyCharsTo(char* const s,const int maxlen)const{ int s.len= len<maxlen ? len : maxlen; if (s.len) memcpy(s,store,s.len);

2003

33/38

BevIT: Programozs II. s[len]=0; } ostream& operator<<(ostream &o,const string &s){ int len=s.Len(); char* ps=new char[len+1]; s.CopyCharsTo(ps,len); o<<ps; delete ps; return o; }

2003

A << opertor tdefinilsa sztringekre


ostream& operator<<(ostream& o,const string &s){ int len=s.len(); char *ps=new char[len+1]; s.CopyCharsTo(ps,len); o<<ps; delete ps; return o; } char& string::operator[](int i){ return store[i]; //memriacmet ad vissza } class sstring::public string{ public: sstring():string(){}; sstring(const string& ps):string(ps){}; bool operator <=(const string& ps)const; }; bool sstring::operator <=(const string& ps)const{ int i=0; while(i<Len() && i<ps.Len() && (*this)[i]==ps[i]) i++; if(i>=Len()) return true; if(i>=ps.len()) return false; return (*this)[i]<=ps[i]; } int main(){ string s(123),s2,s3=s2=s; string s4(13); s3=s3+abcd; //implicit tpuskonverzi s3[2]=c; cout<<(<<s3+ABC+D<<)<<s[1]; cout<<\n<<s4<<<=<<s; if(s4<=s) cout<<igaz\n; else cout<<nem igaz\n; 34/38

BevIT: Programozs II. return 0; }

2003

Tpuskonverzi
C++-ban a tpuskonverzi mindig konstruktorokon keresztl valsul meg. Egy B tpus (osztlyba tartoz) vltoz (objektum) akkor konvertlhat A tpusv (osztlyba tartozv), ha az A osztlyban szerepel B argumentum konstruktor. (B->A tpuskonverzi) Pl.: class A{ public: A (const &B) }; Gyakorlati plda: char char* string sstring

a nyilak konvertlst jeleznek Explicit konverzi: a forrskdban kdrszlet hvja az A osztly B argumentum konstruktort a B>A tpuskonverzi megvalstsra clja olyan fggvny vagy operator hasznlatnak lehetv ttele, amely B argumentummal nem, de A argumentummal rtelmezett. void test(A){}; { test (A (B) ); } //konstruktor

Pl.:

- a tpuskonverzi eredmnyeknt egy A tpus tmeneti vltoz (objektum) jn ltre Implicit tpuskonverzi: A fordt tpuskonverzit vgez, ha egy fggvnyt vagy operatort, mely: a) B argumentummal nem, de A argumentummal rtelmezett b) adott nev fggvnyt vagy operatort B argumentummal hvjuk c) ltezik A-nak B argumentum konstruktora

Pl.: test(B) //B-vel hvjuk Gyakorlati plda: void test(const sstring &s){}; int main(){ string s; sstring ss; test(ss); test(sstring(s)); //explicit: string->sstring konv. test(s); //gy is j; impicit: string->sstring konv. test(sstring(string(abc))); //explicit: char*->sting //explicit: string->sstring konv. test(string(abc)); //explicit: char*->sting 35/38

BevIT: Programozs II. //implicit: string->sstring konv. test(ssting(abc)); //implicit: char*->sting //explicit: string->sstring konv. Megjegyzs: csak egy mlysgig lehet implicit tpuskonverzit vgrehajtani! Pl.: test(abc); //2 mlysg implicit konverzira a fordt nem kpes! Ha lenne a string-nek char* tpus konstruktora, akkor ez is mkdne. Megjegyzs: explicit konverzi tetszleges mlysgben trtnhet.

2003

Sablonok (template-ek) hasznlata:


Clja : Mveletek rtelmezse elre nem definilt osztlyokon, azok bizonyos tulajdonsgait felttelezve. Pl.: ha egy osztlyon rtelmezett a < s az = (legyen egyenl) opertor, akkor sorba rendezhet. Elnyei: o Rvid, knnyen karbantarthat kd o Univerzlis kdrszleteket eredmnyez, mely minden, a felttelt kielgt osztlyra alkalmazhat Htrnyai: o A legtbb fordt a sablonokat csak makrknt kpes kezelni, ezrt a fggvnytrzsek nem fordthatak le, mg a tpusok nem definiltak. o Kvetkezmny: tbb forrsbl felptett kd esetn a sablonnal definilt fggvnyek trzsnek is a header fjlban kell lennie.

//Universal Binary-Tree Sort Feltevsek typ-re: typ-nek van default konstruktora (typ :: typ( );) #include <iostream.h> template <class typ> class tree{ private: typ key; tree *less,*greater; public: tree(const typ i); void Insert(const typ i); void GetContent(typ *t , int &c); ~tree(); }; van copy konstruktora (rtk szerint tadhat)

36/38

BevIT: Programozs II. template <class typ> tree <typ>::tree(const typ i){ key=i; less=0; greater=0; }; van = opertora ( typ = typ) template <class typ> void TreeInsert(tree<typ>*&t,const typ i){ if (t) t->Insert(i); else t=new tree <typ> (i); } template <class typ> void tree<typ>::Insert(const typ i){ if (i<Key) TreeInsert(less,i); else TreeInsert (greater,i); } van < opertora (typ < typ) template <class typ> void tree<typ>::GetContent(typ *t,int &c){ if (less) less->GetContent(t,c); t[c++]=key; if (greater) less->GetContent(t,c); } template <class typ> tree <typ>::~tree(){ if (less) delete less; if (greater) delete greater; }

2003

int main(){ double i,*out; int c=0; char ch; tree <double> *t=0; do{ cout<<Enter a real value:; cin>>i; c++; TreeInsert(t,i); do{ cout<<Is there other value?(y/n); cin>>ch; }while (ch!=y && ch!=n); }while (ch!=n); 37/38

BevIT: Programozs II. out=new double[c]; c=0; t->GetContent(out,c); c=0; cout<<Values in decreasing order:\n; while (c) cout<<out[--c]<< ; delete t; delete out; return 0; }

2003

38/38

BevIT: Programozs II.

2003

Ajnlott irodalom: Stanley B. Lippmann: C++ elszr /Novotrade kiad/ Benk Tiborn, Popper Andrs, Benk Lszl: Bevezets a Borland C++ programozsba Dr. Kondorosi Kroly, Dr Szirmai-Kalos Lszl, Dr. Lszl Zoltn: Objektum orientlt szoftverfejlszts /Computer Book kiad/ A jegyzetet feldolgozta: Borbly Viktor, Bertk Botond eladsai nyomn. Kszlt: 2003

39/38

También podría gustarte