Alkalmazott modul: Programozás 8. előadás. Strukturált programozás: dinamikus memóriakezelés. Dinamikus memóriakezelés. Dinamikus memóriakezelés

Hasonló dokumentumok
Alkalmazott modul: Programozás 10. fejezet. Strukturált programozás: dinamikus memóriakezelés. Giachetta Roberto

Bevezetés a Programozásba II 10. előadás. Dinamikus memóriakezelés

8. gyakorlat Pointerek, dinamikus memóriakezelés

Alkalmazott modul: Programozás 9. előadás. Strukturált programozás: dinamikus adatszerkezetek

Mutatók és mutató-aritmetika C-ben március 19.

C memóriakezelés. Mutató típusú változót egy típus és a változó neve elé írt csillag karakterrel hozhatjuk létre.

A C programozási nyelv V. Struktúra Dinamikus memóriakezelés

Készítette: Nagy Tibor István

OOP #14 (referencia-elv)

5. Gyakorlat. struct diak {

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

C programozási nyelv Pointerek, tömbök, pointer aritmetika

Programozás alapjai. 10. előadás

Bevezetés a Programozásba II 2. előadás. Adattípusok megvalósítása egységbe zárással. Adattípusok megvalósítása egységbe zárással

1. Alapok. Programozás II

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

Pénzügyi algoritmusok

3. Osztályok II. Programozás II

JAVA PROGRAMOZÁS 2.ELŐADÁS

A verem (stack) A verem egy olyan struktúra, aminek a tetejéről kivehetünk egy (vagy sorban több) elemet. A verem felhasználása

Programozási nyelvek Java

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

C++ programozási nyelv Konstruktorok Gyakorlat

Bevezetés a programozásba I.

Programozas 1. Strukturak, mutatok

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

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása

Pénzügyi algoritmusok

Programozási Nyelvek: C++

Osztályok. 4. gyakorlat

Java II. I A Java programozási nyelv alapelemei

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

C++ programozási nyelv Konstruktorok-destruktorok

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

Java II. I A Java programozási nyelv alapelemei

Bevezetés a Programozásba II 3. előadás. Biztonságos adattípusok megvalósítása. Biztonságos adattípusok megvalósítása

Programozási nyelvek a közoktatásban alapfogalmak II. előadás

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós április 4. Széchenyi István Egyetem, Gy r

Maximum kiválasztás tömbben

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

tétel: különböző típusú adatokat csoportosít, ezeket egyetlen adatként kezeli, de hozzáférhetünk az elemeihez is

Informatikai Kar. 3. fejezet. alapismeretek. Giachetta Roberto

Programozás C++ -ban

Programozás. Osztályok, Származtatott osztályok. Fodor Attila

Bevezetés a C++ programozási nyelvbe

7. fejezet: Mutatók és tömbök

Memóriakezelés, dinamikus memóriakezelés

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

Kivételkezelés a C++ nyelvben Bevezetés

A C programozási nyelv III. Pointerek és tömbök.

Programozás I gyakorlat

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

Programozási nyelvek Java

A C programozási nyelv III. Pointerek és tömbök.

A C# programozási nyelv alapjai

Programozás. C++ típusok, operátorok. Fodor Attila

A 32 bites x86-os architektúra regiszterei

Programozási nyelvek I. 5. előadás (Gregorics Tibor anyagának felhasználásával)

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

Adatelérés és memóriakezelés

Tömbök kezelése. Példa: Vonalkód ellenőrzőjegyének kiszámítása

találhatók. A memória-szervezési modell mondja meg azt, hogy miként

Bevezetés a programozásba. 8. Előadás: Függvények 2.

Programozás C++ -ban 2007/4

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

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

Pelda öröklődésre: import java.io.*; import java.text.*; import java.util.*; import extra.*;

Programozás C++ -ban

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

10. gyakorlat Struktúrák, uniók, típusdefiníciók

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

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

Objektumelvű alkalmazások fejlesztése 6. gyakorlat. Öröklődés, polimorfizmus. Öröklődés Kódismétlődés objektum-orientált szerkezetben

Alprogramok, paraméterátadás

500. AA Megoldó Alfréd AA 500.

Bevezetés a programozásba Előadás: A const

C++ programozási nyelv

Bevezetés a programozásba II. 5. Előadás: Másoló konstruktor, túlterhelés, operátorok

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

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

Programozási nyelvek Java

ISA szimulátor objektum-orientált modell (C++)

C++ referencia. Izsó Tamás február 17. A C++ nyelvben nagyon sok félreértés van a referenciával kapcsolatban. A Legyakoribb hibák:

C# osztálydeníció. Krizsán Zoltán 1. .net C# technológiák tananyag objektum orientált programozás tananyag

128. AA Megoldó Alfréd AA 128.

Alkalmazott Modul III 4. előadás. Objektumorientált programozás: objektumok és osztályok. Procedurális programozás Koncepció

1. Mi a fejállományok szerepe C és C++ nyelvben és hogyan használjuk őket? 2. Milyen alapvető változókat használhatunk a C és C++ nyelvben?

Számítógép és programozás 2

Bevezetés a C++ programozási nyelvbe

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

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 alapjai II. (4. ea) C++

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

Programozás C és C++ -ban

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

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

Objektum Orientált Programozás V.

C programozás. 6 óra Függvények, függvényszerű makrók, globális és

Objektumorientált Programozás V.

Programozás BMEKOKAA146. Dr. Bécsi Tamás 5. előadás

Átírás:

Eötvös Loránd Tudományegyetem Informatikai Kar Alkalmazott modul: Programozás 8. előadás Strukturált programozás: dinamikus memóriakezelés Giachetta Roberto groberto@inf.elte.hu http://people.inf.elte.hu/groberto Memóriaszegmensek Az operációs rendszer minden futó program számára fenntart egy területet a memóriából, ezt nevezzük memóriaszegmensnek minden program a saját szegmensében dolgozik, a szegmens mérete változhat futás közben minden szegmensbeli memóriahely (bájt) rendelkezik egy sorszámmal, ez a szegmensbeli memóriacíme, amelyen keresztül elérhető a programban A memória(szegmens) tekinthető egy vektornak, a memóriacím pedig annak egy indexe (általában hexadecimálisan adjuk meg, pl. 0x34c410) 0x34c40f 0x34c410 0x34c411 ELTE IK, Alkalmazott modul: Programozás 8:2 Memóriacím lekérdezése Minden változó rendelkezik memóriacímmel ezt C++-ban hasonlóan kezelhetjük, mint magát a változót mivel a változó típusától függően több bájton is tárolódhat, mindig csak az első bájt címét kapjuk vissza Egy változó memóriacímét az & operátorral kérdezhetjük le, ez a referenciaoperátor, &<változónév> a változó első bájtjának memóriabeli címe int i = 128; cout << i << " " << &i; // lehetséges eredmény: 128 0x22ff6c Műveletek memóriacímekkel Lehetőségünk van a memóriában történő ugrásra a memóriacímet számként kezelhetjük, növelhetjük, illetve csökkenthetjük (a +, -, ++, -- operátorokkal) azonban egy egyszeri növelés esetén a címérték nem eggyel fog nőni, hanem a következő változó címét adja vissza cout << i << << &i << << &i+1; // lehetséges eredmény: 128 0x22ff6c 0x22ff70 0x22ff6c 0x22ff70 ELTE IK, Alkalmazott modul: Programozás 8:3 ELTE IK, Alkalmazott modul: Programozás 8:4 Referencia változók A referencia változók (vagy álnevek) olyan változók, amelyek nem a változók értékét, hanem memóriacíműket másolják át, így ugyanarra a területre mutatnak a memóriában int i = 128; int j = i; // egyszerű változó int& k = i; // referencia változó i j Mutatók deklarálása Egy még speciálisabb változótípus a mutató (pointer), amely memóriacímet tárol értékként mutató létrehozásával egy új adatot viszünk a memóriába, amely másik adat memóriacímét tartalmazza általánosabb célú, mint a referencia A mutató létrehozásakor meg kell adnunk, milyen típusú változó címét fogja eltárolni egy típushoz a hozzá tartozó mutató típus a <típusnév>* mutató létrehozása: <típus> *<mutatónév>; k int* ; // egy int-re mutató pointer ELTE IK, Alkalmazott modul: Programozás 8:5 ELTE IK, Alkalmazott modul: Programozás 8:6 1

Mutatók használata A mutatók hasonlóan viselkednek, mint más változóink értéket adhatunk nekik, élettartammal rendelkeznek az értéküket lehet növelni, csökkenteni (+, -, ++, --), ekkor a megfelelő memóriacímbeli objektumra ugranak mutatókat nem csak változókra, hanem tömbökre és alprogramokra állíthatunk a referenciaváltozókkal ellentétben nem kell nekik adni kezdőértéket A mutató mérete rögzített minden típusra, 32 bites architektúrában 4 byte (emiatt csak 4GB memória címezhető meg), 64 bites architektúrában 8 byte Mutatók használata Mutató értékadására használhatjuk a referencia operátort, így ráállíthatjuk egy már létező változó memóriacímére, pl.: char ch = 'a'; char *chp = &ch; // lekérdezzük ch memóriacímét, amit értékül // adunk chp mutatónak, innentől rámutat chp ch ELTE IK, Alkalmazott modul: Programozás 8:7 ELTE IK, Alkalmazott modul: Programozás 8:8 Mutatók lekérdezése Amikor mutatók értékét kezeljük, akkor egy memóriacímet kapunk, amennyiben az általa mutatott változó értékére vagyunk kíváncsiak, akkor használnunk kell a * operátort, pl.: char ch = 'a', *chp = &ch; // deklarálunk egy karakter változót és egy // mutatót cout << chp; // lekérdezzük a chp tartalmát, azaz ch címét // tehát az eredmény a memóriacím cout << *chp; // lekérdezzük a chp által mutatott változó // tartalmát, az eredmény 'a' lesz cout << &chp; // lekérdezzük a chp mutató címét ELTE IK, Alkalmazott modul: Programozás 8:9 Biztonságos használat Mutatók használata veszélyes lehet, ha olyan mutatóra hivatkozunk, amely nem mutat megfelelő helyre (pl. nem adtunk neki értéket, vagy amit adtunk, már megsemmisült), ekkor szegmenshibát kapunk (futási időben) Célszerű a mutatónak létrehozáskor a nulla (NULL, 0) értéket adni, mert így utólag ellenőrizhető lesz int * = NULL; // vagy int * = 0; if (){ /* ez az ág akkor hajtódik végre, ha nullától különböző értéket tárol */ } ELTE IK, Alkalmazott modul: Programozás 8:10 Mutató, mint bejáró A mutatókat ráállíthatjuk tömbre is (pontosabban az első elemére), illetve használhatjuk tömbök bejárására is, így nem csupán indexeléssel férhetünk hozzá az adatokhoz int array[10]; for (int* p = array; p!= array + 10; p++) // mutató használata indexelés helyett, // ugyanúgy 10 lépést teszünk meg cin >> *p; // tömb eleminek feltöltése // ugyanez rövidebben: int array[10], *p = array; while (p!= array + 10) cin >> *p++; Memóriafoglalási lehetőségek Memóriahelyeket két módon foglalhatunk le (allokálhatunk): automatikusan: változó létrehozásakor lefoglalódik hozzá egy memóriahely is, ezt nem befolyásolhatjuk manuálisan (dinamikusan): lehetőségünk van explicit megadni a kódban, hogy lefoglalunk egy a memóriahelyet ehhez a new operátort használjuk, és meg kell adnunk a típust is, pl. new double; a létrehozás visszaad egy memóriacímet, amelyen a változó elhelyezkedik A lefoglalással visszakapott memóriacímet megkaphatja egy mutató, pl.: int * = new int; ELTE IK, Alkalmazott modul: Programozás 8:11 ELTE IK, Alkalmazott modul: Programozás 8:12 2

Memóriafoglalási lehetőségek szétválaszthatjuk a mutató deklarációját a hozzá tartozó memóriaterület lefoglalásától, pl.: int *; // ekkor i még csak egy mutató = new int; // új memóriaterület a mutatónak két hely kerül lefoglalásra a memóriában, egy a mutatónak, egy az értéknek egy mutató számára többször is lefoglalhatunk helyet, pl.: int * = new int; = new int; = new int; új memóriaterület foglalásakor a régi memóriaterület is bent marad a szegmensben, viszont a mutatón keresztül már nem lesz elérhető (de memóriaműveletekkel igen) ELTE IK, Alkalmazott modul: Programozás 8:13 Memóriaterületek A programok a használat szempontjából három memóriaterületet különböztetnek meg: globális terület (global): konstansok és globális változók, amelyek a program futása során mindig jelen vannak verem (stack): a lokális változók, amelyeket automatikusan hoztunk létre működésében olyan, mint egy verem, mert mindig az utolsó blokkban létrehozott változók törlődnek elsőként a blokkból való kilépéssel kupac (heap): a manuálisan lefoglalható memóriaterület, általában a legnagyobb részét képezi a szegmensnek a tömbök és a szövegek is ide kerülnek ELTE IK, Alkalmazott modul: Programozás 8:14 Memóriahely felszabadítás Ahogy lefoglalunk, úgy lehetőségünk van törölni is memóriahelyet a programunkban az automatikusan lefoglalt memória törlését a program magától végzi, ezt nem befolyásoljuk a manuálisan létrehozott memóriahelyeket nekünk kell törölnünk, vagy a program végéig a memóriában maradnak a törlésre a delete operátor szolgál float* flp = 0; // flp nem hivatkozik semmire flp = new float; // manuálisan lefoglaljuk a helyet delete flp; // töröljük a lefoglalt helyet Biztonságos dinamikus helyfoglalás Minden new operátornak kell rendelkeznie egy delete párral, azaz a dinamikusan létrehozott változókat törölni is kell A nem törölt, dinamikusan lefoglalt változók a mutató törlését követően is a memóriában maradnak, az ilyen területeket nevezzük memóriaszemétnek, pl.: int * = new int; // dinamikusan lefoglaltuk a memóriaterületet = new int; // ekkor az előző terület memóriaszemét lesz Sosem a mutatót, csak a dinamikusan lefoglalt területet kell manuálisan törölnünk (ha több mutató hivatkozik ugyanarra a területre, elég egyszer elvégeznünk a törlést) ELTE IK, Alkalmazott modul: Programozás 8:15 ELTE IK, Alkalmazott modul: Programozás 8:16 Többszörös dinamikus foglalás Egyszerre több memóriahelyet is lefoglalhatunk azonos típusból a [] operátorral, ekkor azok egymás után helyezkednek el a memóriában, pl.: int * = new int[5]; // öt memóriahely lefoglalása törlésnél a delete operátornak jelölnünk kell, hogy több helyről van szó, szintén a [] operátorral, pl.: delete[] ; ha törlésnél elfelejtjük a jelölést, akkor csak az első érték törlődik, a többi a memóriában marad a törlés után a mutató továbbra is használható, de az értékek elvesznek ELTE IK, Alkalmazott modul: Programozás 8:17 ELTE IK, Alkalmazott modul: Programozás 8:18 3

= new int; // memóriahely foglalás = new int; // memóriahely foglalás * = ; // érték beállítása ELTE IK, Alkalmazott modul: Programozás 8:19 ELTE IK, Alkalmazott modul: Programozás 8:20 = new int; // memóriahely foglalás * = ; // érték beállítása = new int; = new int; // memóriahely foglalás * = ; // érték beállítása = new int; delete ; // memóriahely törlése, -ben megmarad a cím ELTE IK, Alkalmazott modul: Programozás 8:21 ELTE IK, Alkalmazott modul: Programozás 8:22 = new int; // memóriahely foglalás * = ; // érték beállítása = new int; delete ; // memóriahely törlése, -ben megmarad a cím = new int[2]; // 2 memóriahely foglalása = new int; // memóriahely foglalás * = ; // érték beállítása = new int; delete ; // memóriahely törlése, -ben megmarad a cím = new int[2]; // 2 memóriahely foglalása delete[] ; // törlés ELTE IK, Alkalmazott modul: Programozás 8:23 ELTE IK, Alkalmazott modul: Programozás 8:24 4

= new int; // memóriahely foglalás * = ; // érték beállítása = new int; delete ; // memóriahely törlése, -ben megmarad a cím = new int[2]; // 2 memóriahely foglalása delete[] ; // törlés = NULL; // újbóli kinullázás A primitív dinamikus tömb A többszöri memóriafoglalással tulajdonképpen egy tömböt hozhatunk létre, amely a primitív tömb dinamikus megfelelője az elemei elérhetőek a [] operátorral, 0-tól indexelve működése lényegében megegyezik a statikus dinamikus tömbével, de paraméterben megadható változó is méretnek int size; cin >> size; int* array = new int[size]; // tömb lefoglalása for (int i = 0; i < size; i++) cin >> array[i]; // elemek bekérése delete[] array; // tömb törlése ELTE IK, Alkalmazott modul: Programozás 8:25 ELTE IK, Alkalmazott modul: Programozás 8:26 Tömbelem címzés A tömbelem indexelés igazából a memóriában való címelérés, és egyenértékű a + operátor használatával azaz a[i] leírható *(a+i) formában is, vagyis a tömb kezdőcímétől (a) szeretnénk továbblépni indexnyi (i) helyet a memóriában, és az ottani értéket lekérdezni ezért indexelünk 0-tól, mivel a tömb kezdőcíme egyben az első elem címe float* a = new float[10]; cin >> a[5]; // ugyanez: cin >> *(a+5); // ugyanez: cin >> 5[a]; (kommutativitás miatt) Konstans mutatók és referenciák Referencia, illetve mutató változók is lehetnek konstansok referencia esetén az érték nem módosítható: <típus> const &<név> = <változó>; mutató esetén kétféle módon is korlátozhatjuk a használatot lehet a mutatott érték konstans, ekkor nem változtatható a hivatkozott változó értéke, de a mutató átállítható: <típus> const *<név>; lehet a mutató konstans, ekkor nem állítható át másik memóriacímre, de a mutatott érték változtatható: <típus> * const <név> = <változó>; lehet a mutató és a mutatott érték is konstans: <típus> const * const <név>; ELTE IK, Alkalmazott modul: Programozás 8:27 ELTE IK, Alkalmazott modul: Programozás 8:28 Konstans mutatók és referenciák Pl: double d1 = 10, d2 = 50; double const &d1r = d1; // konstans referencia double const * d1p1 = &d1; // mutató konstansra double * const d1p2 = &d1; // konstans mutató double const * const d1p3 = &d1; // konstans mutató konstans értékre d1r = 100; // HIBA, az érték nem módosítható *d1p1 = 50; // HIBA, az érték nem módosítható *d1p2 = 50; // az érték módosítható *d1p3 = 50; // HIBA d1p1 = &d2; // átállíthatjuk más memóriacímre d1p2 = &d2; // HIBA, a mutató nem állítható át d1p3 = &d2; // HIBA Mutatóra állított mutatók és referenciák Mivel a mutatók is értékek, rájuk is lehet mutatót állítani ekkor jeleznünk kell, hogy a mutató célja is mutató, azaz halmoznunk kell a * jelet int value = 0; int *intp = &value; int **intpp = &intp; // mutatóra állított mutató cout << **intpp; // kiírja value értékét hasonlóan referencia is állítható mutatóra, így a mutató is használható cím szerinti paraméterátadáskor, pl.: int *&intpref = intp; cout << *intpref; // kiírja value értékét ELTE IK, Alkalmazott modul: Programozás 8:29 ELTE IK, Alkalmazott modul: Programozás 8:30 5

Többdimenziós tömbök Ezzel a módszerrel lehetőségünk van többdimenziós tömbök (mátrixok) létrehozására is tömbök tömbjeként, a külső tömbünk fogja tartalmazni a mutatókat, amelyek a mátrix soraira hivatkoznak Többdimenziós tömbök a mátrix megjelenése a memóriában: matrix létrehozzuk a mutatókat tároló tömböt, majd utána mindegyikre felfűzzük az értékeket tároló tömböt, tehát egy ciklusra van szükségünk, pl.: float** matrix = new float*[width]; // 4 sora lesz a mátrixnak for (int i = 0; i < width; i++) matrix[i] = new float[height]; // 3 oszlopa lesz a mátrixnak matrix[0] matrix[0][0] matrix[3] matrix[1][0] ELTE IK, Alkalmazott modul: Programozás 8:31 ELTE IK, Alkalmazott modul: Programozás 8:32 Többdimenziós tömbök a létrehozást követően az indexelés és a sorok hozzáférése a megszokott módon történik, pl.: cin >> matrix[3][2]; // elem bekérése cout << **matrix; // mátrix 1. sorának 1. eleme float* row = matrix[3]; // sor átadása egy mutatónak törléskor külön kell törölnünk minden sort, majd a mutatókat tartalmazó tömböt, pl.: for (int i = 0; i < width; i++) delete[] matrix[i]; // sorok törlése delete[] matrix; // mutatók törlése ugyanez megvalósítható magasabb dimenziókban is, pl.: float*** m3d = new float**[width]; Dinamikusan foglalt mezők Természetesen típusok mezői is lehetnek mutatók, és allokálhatunk nekik dinamikusan memóriaterületet ezt általában a konstruktorban végezzük de az így létrehozott értékeket manuálisan kell törölni, különben a példány megsemmisülése után is megmarad a törlést akkor kell elvégezni, amikor a példány törlődik A típuspéldány megsemmisítéséért felelős műveletet nevezzük destruktornak a destruktor automatikusan lefut, amikor törlődik a változó (lokális változó esetén a blokk végére érünk, dinamikus létrehozás esetén meghívjuk a delete műveletet) ELTE IK, Alkalmazott modul: Programozás 8:33 ELTE IK, Alkalmazott modul: Programozás 8:34 Destruktor A destruktorban olyan utasításokat tárolunk, amelyek kitakarítják az általunk használt memóriaterületet csak a dinamikusan foglalt mezőket kell törölnünk ha nincs dinamikusan foglalt mező, akkor nem szükséges A destruktor a ~<típusnév> nevet kapja, mindig publikus, nincs típusa, nincs paramétere, ezért nem túlterhelhető: class <típus> { public: <typusnév>() { } // konstruktor ~<típusnév>() { } // destruktor }; Destruktor struct MyType { MyType(){ cout << "Hello!" << endl; } ~MyType(){ cout << "Byebye!" << endl; } }; int main(){ MyType mt; // itt fut le a konstruktor return 0; } // itt fut le a destruktor // eredménye: // Hello! // Byebye! ELTE IK, Alkalmazott modul: Programozás 8:35 ELTE IK, Alkalmazott modul: Programozás 8:36 6

Feladat: Módosítsuk úgy a verem típust, hogy paraméterben lehessen megadni a maximális elemszámot. dinamikus tömbre van szükségünk (T* _values), amely méretét a konstruktorparaméter adja meg, amit szintén eltárolunk (int _size) a törlés miatt szükségünk lesz destruktor műveletre is Tervezés: _values _top _size Megoldás: template <class T> // elemtípus sablonja class Stack { // verem típus private: T* _values; // értékek mutatója int _top; // a tetőelem indexe int _size; // méret eltárolása public: enum Exceptions { BAD_SIZE, STACK_FULL, STACK_EMPTY }; // kivételek felsorolási típusa }; ELTE IK, Alkalmazott modul: Programozás 8:37 ELTE IK, Alkalmazott modul: Programozás 8:38 Megoldás: template <class T> Stack<T>::Stack(int size) { if (size <= 0) // ellenőrizzük a paramétert throw BAD_SIZE; _values = new T[size]; // tömb dinamikus létrehozása _top = 0; // kezdetben 0 elem van a veremben _size = size; } template <class T> Stack<T>::~Stack() { delete[] _values; // dinamikus tömb törlése } ELTE IK, Alkalmazott modul: Programozás 8:39 7