Programozás C++ -ban 2007/4



Hasonló dokumentumok
Programozás C++ -ban

Programozás C és C++ -ban

Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia

4. Öröklődés. Programozás II

Programozás II gyakorlat. 4. Öröklődés

Osztály és objektum fogalma

Programozás C++ -ban 2007/3

Bevezetés a Programozásba II 11. előadás. Adatszerkezetek megvalósítása. Adatszerkezetek megvalósítása Adatszerkezetek

C++ programozási nyelv Struktúrák a C++ nyelvben Gyakorlat

Objektumorientált programozás C# nyelven

A C++ öröklés. (Előfeltétel: 12. tétel ismerete)

Programozás II. 4. Dr. Iványi Péter

Programozási alapismeretek :: beadandó feladat. Felhasználói dokumentáció. Molnár Tamás MOTIABT.ELTE

Programozás C++ -ban 2007/7

117. AA Megoldó Alfréd AA 117.

Származtatási mechanizmus a C++ nyelvben

0.2.1 Operátorok túlterhelése (műveletek definiálhatók felhaszn. típusokra) Kutya. Eb1. Eb2. Név (txt): Rex. Blöki. Német juhász 3

STL. Algoritmus. Iterátor. Tároló. Elsődleges komponensek: Tárolók Algoritmusok Bejárók

Objektumorientált programozás C# nyelven

Programozás C++ -ban

Programozás II. 6.Öröklés Dr. Iványi Péter

Pénzügyi algoritmusok

PHP II. WEB technológiák. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) PHP II / 19

C++ programozási nyelv Konstruktorok-destruktorok

A lista eleme. mutató rész. adat rész. Listaelem létrehozása. Node Deklarálás. Létrehozás. Az elemet nekünk kell bef zni a listába

Programozás C++ -ban

Egységes és objektumközpontú adatbázis-kezelés (2. rész)

Bevezetés a programozásba 2

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

500. AA Megoldó Alfréd AA 500.

Bevezetés, a C++ osztályok. Pere László

OAF Gregorics Tibor: Minta dokumentáció a 3. házi feladathoz 1.

Dinamikus csatolású függvénykönyvtár készítése és használata Plugin-szerű betöltés Egyszeű C++ osztályok készítése

C++ programozási nyelv

PROGRAMOZÁSI NYELVEK - CPP. GYAKORLAT JEGYZET

Bánsághi Anna

Programozás II. 2. Dr. Iványi Péter

PROGRAMOZÁSI NYELVEK - CPP. GYAKORLAT JEGYZET

Rekurzió. Horváth Gyula.

Bevezetés a C++ programozásba

500. CC Megoldó Alfréd CC 500.

0.1. Mi az a standard be- és kimenet? A két mintafeladat leírása

Objektumorientált programozás C# nyelven

Programozás alapjai II. (9. ea) C++ többszörös öröklés, cast, perzisztencia

Emlékeztető: a fordítás lépései. Szimbólumtábla-kezelés. Információáramlás. Információáramlás. Információáramlás.

Programozás 6. Dr. Iványi Péter

Programozás 5. Dr. Iványi Péter

Bevezetés a C++ programozási nyelvbe

infix kifejezés a+b ab+ +ab postfix kifejezés prefix kifejezés a+b ab+ +ab a+b ab+ +ab Készítette: Szabóné Nacsa Rozália

Bevezetés a programozásba Előadás: Tagfüggvények, osztály, objektum

Informatikai Kar. 3. fejezet. alapismeretek. Giachetta Roberto

A feladat lényege egy felhasználói típusnak a zsák típusnak a megvalósítása.

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

3. Osztályok II. Programozás II

500. DD Megoldó Alfréd DD 500.

Programozás III CSOMAGOK. Az összetartozó osztályok és interfészek egy csomagba (package) kerülnek.

Programozás. C++ osztályok. Fodor Attila. Pannon Egyetem Műszaki Informatikai Kar Villamosmérnöki és Információs Rendszerek Tanszék

Objektumorientált programozás C# nyelven III.

A PROGAMOZÁS ALAPJAI 1. Függvény mint függvény paramétere. Függvény mint függvény paramétere. Függvény mint függvény paramétere


Programozás C++ -ban 2007/1

Statikus adattagok. Statikus adattag inicializálása. Speciális adattagok és tagfüggvények. Általános Informatikai Tanszék

Elemi Alkalmazások Fejlesztése II.

PHP5 Új generáció (2. rész)

Programozás II gyakorlat. 8. Operátor túlterhelés

128. AA Megoldó Alfréd AA 128.

C# osztályok. Krizsán Zoltán

228. AA Default Konstruktor AA 228.

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

Visual C++ osztály készítése, adattagok, és metódusok, láthatóság, konstruktor, destruktor. Objektum létrehozása, használata, öröklés.

Körkörös listák. fej. utolsó. utolsó. fej

Programozás C nyelven FELÜLNÉZETBŐL elhullatott MORZSÁK. Sapientia EMTE

1 Rev 4. A C++ programozás alapjai- segédlet

#include <iostream> using namespace std; // struct macska is lehetne class macska { public: int kor; int suly; }; void main() { macska cirmi;

A Jáva programozási nyelv rejtelmei

XIII. STL. Tároló Bejáró Algoritmus. XIII.1 A vector #include <vector> #include <vector> #include <algorithm> using namespace std;

Szövegek C++ -ban, a string osztály

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Programozás C és C++ -ban

Bánsághi Anna

1. Alapok. Programozás II

Programozás II. 3. gyakorlat Objektum Orientáltság C++-ban

Java és web programozás

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

- 1 - Konstansok használata. Döntsük el, van-e fordítási idejű hiba az alábbi programrészletekben! a) const char * str="zh"; str[0]++;

Információs Technológia

Java programozási nyelv 4. rész Osztályok II.

Programozás alapjai II. (1. ea) C++

Programozás alapjai II. (1. ea) C++

osztályok kapcsolata Származtatatás C++ Izsó Tamás március 19. Izsó Tamás Származtatatás/ 1

0. Megoldó Manó 0. Programozás alapjai 2. (inf.) pót zárthelyi gyak. hiányzás: 2 n/kzhp: n/11,5. ABCDEF IB.028/2.

Programozási technikák Pál László. Sapientia EMTE, Csíkszereda, 2009/2010

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

Adatszerkezetek és algoritmusok

Osztályok. 4. gyakorlat

Java és web programozás

Országzászlók (2015. május 27., Sz14)

C++ Gyakorlat jegyzet 5. óra. A C++ szabvány több memóriatípust különít el. Ezek közül elsősorban a stack-et használtuk eddig.

Eseményvezérelt alkalmazások fejlesztése II. A.NET keretrendszer és a C# programozási nyelv. Objektumorientált programozási nyelvek A Smalltalk nyelv

Géptermi zh-írás forgatókönyve

Átírás:

Programozás C++ -ban 2007/4 1. Az adatokhoz való hozzáférés ellenőrzése Egy C programban a struktúrák minden része mindig elérhető. Ugyanakkor ez nem a legkedvezőbb helyzet. Több szempontból is hasznos ha a felhasználót "távol tudjuk tartani" a struktúra belső részleteitől. Például a felhasználót nem fogja zavarni és nem kell újraírnia a programját ha a struktúra belső felépítése megváltozik. A C++ lehetővé teszi hogy korlátozzuk, vagy megengedjük a belső részeihez való hozzáférést. A C++ három kulcsszót deklarál: A kulcsszó jelentése, hogy minden további deklaráció a struktúrában szabadon elérhető. private: A kulcsszó jelentése, hogy a további deklarációk mások számára nem elérhetőek, csak a struktúra létrehozója látja, tudja használni. protected: A kulcsszó jelentése hasonló a private kulcsszóhoz egy fontos különbséggel, mely később nyer értelmet. Egy egyszerű példa látható alább: struct B private: char j; float f; int i; void func(); ; void B::func() i = 0; j = '0'; f = 0.0; ; int main() B b; b.i = 1; // OK public //! b.j = '1'; // Illegalis private //! b.f = 1.0; // Illegalis private Ezt a típusú hozzáférés ellenőrzést az objektum-orientált környezetben a implementáció elrejtésének (implementation hiding) szokták hívni.

Az egységbezárás és a hozzáférés ellenőrzés tulajdonképpen már jóval több mint egy C struktúra. Ebben az esetben már az objektum-orientált területen járunk és ezt az új típusú dolgot osztálynak (class) nevezik. 1.1 Az osztály (class) A C++ -ban a struktúrák és az osztályok szinte azonosak, egy fontos tulajdonságot kivéve. Az osztály (class) elemei alapesetben private jellegűek, míg a struktúra (struct) elemei alapesetben public jellegűek. Nézzünk egy egyszerű összehasonlítást. struct A private: int i, j, k; int f(); void g(); ; int A::f() return i + j + k; void A::g() i = j = k = 0; class B int i, j, k; int f(); void g(); ; int B::f() return i + j + k; void B::g() i = j = k = 0; Az osztályt a C++ -ban a class kulcsszóval jelöljük. 2. Egy példa az osztályokra Módosítsuk az előző fejezetben deklarált verem struktúrát olyan módon hogy most mint osztályt deklaráljuk. A struktúrába foglalt adatok privát adatok lesznek. Ebben az esetben az adatszerkezet implementációja anélkül változtatható meg, hogy az adatszerkezetet használó programokat módosítani kellene. #ifndef STACK_H #define STACK_H #define VEREM_SIZE 100 class verem private: int size; // a verem elemek szama

int data[verem_size]; // az elemek void init(); void push(int item); int pop(); int count(); void final(); ; #endif STACK_H 3. Inicializálás és takarítás Az egyik legnagyobb probléma a C nyelven írt könyvtárakkal, illetve a könyvtárakban deklarált függvényekkel az, hogy gyakran a felhasználó elfelejti inicializálni a könyvtárat, a változót vagy elfelejti felszabadítani a változó memóriáját. A C++ programozási nyelvben ez a hiba nagyon könnyen elkerülhető. Az előzőekben megismert két adatstruktúra, a verem és a Stack, tartalmazott egy inicializáló függvényt. A név jelzi, hogy azelőtt kellene ezt a függvényt meghívni mielőtt elkezdjük használni a struktúrát. Ez könnyen elfelejthető. Mivel a C++ programozási nyelv minnél kevesebb hibalehetőséget akar engedni, az inicializálás és felszabadítás (takarítás) feladatát az osztályt kitaláló, deklaráló személyre bízza, hiszen Ő ismeri és tudja, hogy hogyan kell ezeket a feladatokat végrehajtani. Egy osztály inicializálást garantálni lehet egy konstruktor (constructor) függvénnyel. Ha egy osztályban deklarálva van egy konstruktor, akkor ez még azelőtt végrehajtódik, mielőtt az osztályt használó személy használni tudná az osztályt. A függvény lefutása nem opcionális, mindeképpen lefut! A konstruktor függvény neve ugyanaz mint az osztály neve és nincs típusa! Ez nem azt jelenti hogy a függvénynek void típusa van. Egyszerűen nincs típusa! Ez egy speciális eset. Ugyanakkor argumentumokat is megadhatunk a konstruktornak, amint ezt majd a példákban látni fogjuk. A konstruktor párja a desktruktor mely megszünteti az objektumot. Például felszabadítja a memóriát, stb. A szintaxisa hasonló a konstruktoréhoz, neve megegyezik az osztály nevével, de a neve előtt egy tilda (~) van. A desktruktornak nincs típusa és nincs argumentuma! A destruktor is automatikusan hívódik meg, amikor az obejktum megszűnik, például a definiálásának hatóköre megszünik. (A definiálás hatóköre megszünik, amikor már többé nem érvényes. Például egy objektum csak a nyitó és a záró kapcsos zárójelek között érvényes. Amikor a program futása eléri a záró kapcsos zárójelet az objektum megszűnik.) Nézzünk egy példát.

#include <iostream> using namespace std; class Tree int height; Tree(int initialheight); // konstruktor ~Tree(); // destruktor void grow(int years); void printsize(); ; Tree::Tree(int initialheight) height = initialheight; Tree::~Tree() cout << "Tree destruktorban" << endl; printsize(); void Tree::grow(int years) height += years; void Tree::printsize() cout << "Tree magassaga " << height << endl; int main() cout << "kezdo zarojel elott" << endl; Tree t(12); cout << "Tree letrehozasa utan" << endl; t.printsize(); t.grow(4); cout << "kezdo zarojel elott" << endl; cout << "kezdo zarojel utan" << endl; return 0; contructor1.cpp

A program futásának eredménye a következő lesz. kezdo zarojel elott Tree letrehozasa utan Tree magassaga 12 kezdo zarojel elott Tree destruktorban Tree magassaga 16 kezdo zarojel utan Látható a záró kapcsos zárójel elérésével a Tree objektum megszűnik, a destruktor függvény automatikusan meghívódik. Megjegyzés: Nem véletlen lehetőség a C++ programozási nyelvben, hogy a változókat bárhol definiálhatjuk. Erre a leheségre szükség lehet például az objektumok inicializálása során is. Például ha egy objektumot egy blokk elején lehet csak definiálni akkor a konstruktor hiába fut le, hiszen a végrehajtásához szükséges egyéb információ még nem áll rendelkezésre (a többi változót is éppen hogy csak deklaráljuk a blokk elején). 3.1 Stack objektum konstruktorral Nézzük meg a korábban látott Stack objektumot konstruktorral és destruktorral. #ifndef STACKOBJ_H #define STACKOBJ_H class Stack struct Link void* data; Link* next; Link(void* dat, Link* nxt); ~Link(); * head; Stack(); ~Stack(); void push(void* dat); void* peek(); void* pop(); ; #endif stackobj.h

#include "stackobj.h" #include <iostream> #include <cassert> using namespace std; Stack::Link::Link(void* dat, Link* nxt) data = dat; next = nxt; Stack::Link::~Link() Stack::Stack() head = 0; void Stack::push(void* dat) head = new Link(dat, head); void* Stack::peek() assert(head!= NULL); return head->data; void* Stack::pop() if(head == NULL) return 0; void* result = head->data; Link* oldhead = head; head = head->next; delete oldhead; return result; Stack::~Stack() assert(head == 0); stackobj.cpp A Link::Link konstruktor egyszerűen csak inicializálja a data és next változókat, így amikor a Stack::push függvény végrehajtja a head = new Link(dat, head); sort nem csak egy új objektumot hoz létre de a változók is rögtön inicializálódnak. Felmerülhet az a kérdés is hogy a Link destruktora miért nem szabadítja fel a benne tárolt adatot. Az egyik probléma hogy a delete függvény nem tud void pointer adatot felszabadítani (illetve ez nem engedélyezett C++ -ban). A másik probléma,

hogy kié az adat melyet a Stack tárol. Valójában a tárolt adat egy külső adat és nem a Stack vagy a Link objektum dolga azt felszabadítani. Ezt azzal is mutatjuk, hogy a Stack destruktora ellenőrzi hogy a Stack üres-e. Az alábbi példa pedig azt mutatja, hogy mennyivel egyszerűsíti az objektumorientáltság a korábbi test programot. A példa azt is mutatja, hogy a program argumentumai C++ -ban ugyanúgy használhatók argc és argv paraméterek egy program argumentumainak megállapítására mint C-ben. Figyeljük meg mennyivel egyszerűsödött a kód és hogy nem kell foglalkoznunk az inicializálással és a felszabadítással. #include "stackobj.h" #include <fstream> #include <iostream> #include <string> #include <cassert> using namespace std; int main(int argc, char* argv[]) assert(argc == 2); ifstream in(argv[1]); Stack textlines; string line; while(getline(in, line)) textlines.push(new string(line)); string* s; while((s = (string*)textlines.pop())!= 0) cout << *s << endl; delete s; return 0; stackobjtest.cpp 3.2 Többszörös inicializálás Előfordulhat, hogy nem csak egy objektumot, hanem egyszerre többet is inicializálni kell. Nézzük először azt az esetet amikor egy objektumot inicializálunk és az objektum minden eleme public, vagyis mindenki számára elérhető és nincs konstruktor: struct X int i;

double f; char c; ; X x1 = 1, 2.2, 'c' ; A fenti példában 1 az i változóhoz, 2.2 az f változóhoz és 'c' a c változóhoz rendelődik. A C++ fordító itt is figyel arra, hogy megfelelő típusú változókkal inicializáljuk az objektumot. Abban az esetben, ha objektumok tömbjeit deklaráljuk és inicializáljuk egyszerre hasonlóan lehet eljárni: X x2[3] = 1, 1.1, 'a', 2, 2.2, 'b' ; Néhány dolgot azért meg kell jegyezni: Az értékeket sorrendben fogja a program az egyes objektumok változóihoz rendelni Nem szükséges annyi inicializáló adatot megadni, ahány objektumot deklarálunk, mert a maradék objektumok változóihoz zérust vagy azzal egyenértékű értéket rendelünk. Ez a módszer csak akkor működik, ha az objektum minden tagja public és nincs konstruktor definiálva Bár nincs konstruktor definiálva, de valójában a fordító létrehoz egy alap konstruktort, mely a fenti inicializálást végrehajtja. Ha egy objektum bármely tagja private, vagy egy konstruktor definiálva van akkor az inicializálás csak a konstruktorral lehetséges. Például egy objektum konstruktorral: struct Y float f; int i; Y(int a); ; és az inicializálás az alábbi módon lehetséges: Y y1[] = Y(1), Y(2), Y(3) ; Ezután nézzük meg, hogy hogyan néz ez ki egy komplex példán: #include <iostream> using namespace std; class Z

int i, j; Z(int ii, int jj); void print(); ; Z::Z(int ii, int jj) i = ii; j = jj; void Z::print() cout << "i = " << i << " j = " << j << endl; int main() Z zz[4] = Z(1, 2), Z(3, 4), Z(5, 6), Z(7, 8) ; for(int i = 0; i < 4; i++) zz[i].print(); return 0; multiconstr.cpp Gyakorlatok Egészítsük ki a verem objektumot konstruktorral és destruktorral. Írjon egy osztályt, Simple, melynek egy konstruktora van és kiírja amikor meghívják. A main függvényben deklaráljunk egy Simple objektumot. Próbáljuk ki ezt az egyszerű programot. Az előző példában deklarált objektumot egészítsük ki egy destruktorral, mely szintén csak egy üzenetet ír ki. Ezt a programot is próbáljuk ki. Módosítsuk az előző példát olyan módon, hogy az objektumban deklarálunk egy egész változót. A konstruktornak egy argumentuma legyen egy egész szám, melyet eltárol a változóban. Mind a konstruktort, mind a destruktort módosítsuk olyan módon, hogy kinyomtatja az objektum változóját.