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

Hasonló dokumentumok
Programozás alapjai II. (7. ea) C++

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

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

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

Programozás alapjai 2. (2. ea) C++

117. AA Megoldó Alfréd AA 117.

3. Osztályok II. Programozás II

128. AA Megoldó Alfréd AA 128.

Programozás alapjai II. (8. ea) C++ bejárók és egy tervezési példa

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

.AA Megoldó Alfréd AA.

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

Programozás alapjai C nyelv 7. gyakorlat. Függvények. Függvények(2)

Függvények. Programozás alapjai C nyelv 7. gyakorlat. LNKO függvény. Függvények(2) LNKO függvény (2) LNKO függvény (3)

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

1.AA MEGOLDÓ BERCI AA 1.

Az alábbi példában a Foo f(5); konstruktor hívása után mennyi lesz f.b értéke? struct Foo { int a, b; Foo(int c):a(c*2),b(c*3) {} };

1. Alapok. Programozás II

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

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

C++ programozási nyelv Konstruktorok-destruktorok

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

Programozás alapjai II. (3. ea) C++ Programfejlesztés. Néhány programozási módszer. Feladatanalízis. Modellezés Tervezés. Implementáció (programozás)

500. AA Megoldó Alfréd AA 500.

500. CC Megoldó Alfréd CC 500.

1. Bevezetés A C++ nem objektumorientált újdonságai 3

Programfejlesztés. Programozás alapjai II. (3. ea) C++ Néhány programozási módszer. Korai szoftverkészítés jellemzői. Gépi nyelv? Strukturált tervezés

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.

503.AA Megoldo Arisztid 503.A

Programozás alapjai II. (2. ea) C++ Programfejlesztés. Néhány programozási módszer. Feladatanalízis. Modellezés Tervezés. Implementáció (programozás)

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

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

C++ Gyakorlat jegyzet 8. óra

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

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

1000.AA Megoldo Alfréd 1000.A

Osztály és objektum fogalma

1) Hány byte-on tárol a C++ egy karaktert (char)? implementáció-függő ( viszont lásd 79. megjegyzés ) 1 8 4

Fejlett programozási nyelvek C++ Sablonok és adatfolyamok

228. AA Default Konstruktor AA 228.

Pénzügyi algoritmusok

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

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

Alprogramok, paraméterátadás

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

500.AJ Megoldó Magyar Magdolna 500.J

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

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

500.AA Megoldó Kulcsár 500.A

C++ Standard Template Library (STL)

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

Programozás alapjai C nyelv 5. gyakorlat. Írjunk ki fordítva! Írjunk ki fordítva! (3)

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

Programfejlesztés. Programozás alapjai II. (3. ea) C++ Néhány programozási módszer. Korai szoftverkészítés jellemzői. Gépi nyelv? Strukturált tervezés

Programozási Nyelvek: C++

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

Programozás alapjai II. (2. ea) C++ Programfejlesztés. Néhány programozási módszer. Feladatanalízis. Modellezés Tervezés. Implementáció (programozás)

feladat pont min elért

Pénzügyi algoritmusok

feladat pont min elért

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

500. DD Megoldó Alfréd DD 500.

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

Fejlett programozási nyelvek C++ Iterátorok

Objektumok inicializálása

Bevezetés a programozásba 2

Felhasználó által definiált adattípus

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

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

Bevezetés a programozásba előadás: Öröklődés

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

500.AA Megoldo Arisztid 500.A

Osztályok. 4. gyakorlat

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

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

Programozás C++ -ban

Bánsághi Anna 2014 Bánsághi Anna 1 of 33

Programozás módszertan

Java és web programozás

Programozás C++ -ban

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

Mit ír ki? feladatok megoldásokkal

Programozás II gyakorlat. 6. Polimorfizmus

Programozás C++ -ban 2007/4

Pénzügyi algoritmusok

111. AA Megoldó Alfréd AA 111.

Maximum kiválasztás tömbben

Tervminták II. (Híd, Bejáró, Gyártófüggvény) Halmaz és bejárása Osztály-sablonok

Java és web programozás

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

8. gyakorlat Pointerek, dinamikus memóriakezelés

C++ programozási nyelv

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

- 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]++;

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.

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

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

Programozás alapjai II. (3. ea) C++ Panaszok kezelése. Hol tartunk?

Programozási nyelvek Java

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

Átírás:

Programozás alapjai II. (7. ea) C++ generikus szerkezetek, template Szeberényi Imre, Somogyi Péter BME IIT <szebi@iit.bme.hu> M Ű E G Y E T E M 1 7 8 2 C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 1 - Hol tartunk? C C++ javítások OBJEKTUM: konkrét adat és a rajta végezhető műveletek összessége OO paradigmák egységbezárás (encapsulation), többarcúság (polymorphism), példányosítás (instantiation), öröklés (inheritance), generikus szerkezetek OO dekompozíció, tervezés A C++ csupán eszköz Elveket próbálunk elsajátítani Újrafelhasználhatóság C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 2 - Hol tartunk? /2 objektum megvalósítása osztály (egységbe zár, és elszigetel), konstruktor, destruktor, tagfüggvények inicializáló lista (tartalmazott obj. és ős osztály inicializálása) függvény túlterhelés és felüldefiniálás (overload, override) barát és konstans tagfüggvények dinamikus adat (erőforrás) külön kezelést igényel öröklés és annak megvalósítása védelem enyhítése virtuális függvények, absztrakt osztályok Mi az objektummodell haszna? A valóságos viselkedést írjuk le Könnyebb az analógia megteremtése Láttuk a példát (dig. áramkör modellezése) Digitális jel: üzenet objektum Áramköri elemek: objektumok Objektumok a valós jelterjedésnek megfelelően egymáshoz kapcsolódnak. (üzennek egymásnak) Könnyen módosítható, újrafelhasználható Funkcionális dekompozícióval is így lenne? C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 3 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 4 - Ismétlés (alakzat) class Alakzat { Tartalmazott objektumok Pont p0; ///< alakzat origója Szin sz; ///< alakzat színe Alakzat(const Pont& p0, const Szin& sz) :p0(p0), sz(sz) { Adattagok inicializálása Pont getp0() const { return p0; Szin getsz() const { return sz; virtual void rajzol() const = 0; void mozgat(const Pont& d); virtual ~Alakzat() { ; Virtuális destruktor Virtualis rajzol. Leszármazottban valósul meg. Ismétlés (alakzat) /2 class Poligon : public Alakzat { unsigned int np; Pont *pontok; Ős inicializálása Poligon(const Poligon&); Ne legyen Poligon& operator=(const Poligon&); használható Poligon(const Pont& p0, const Szin sz) :Alakzat(p0, sz), np(1), pontok(new Pont[np-1] { int getnp() const { return np; Pont getcsp(unsigned int i) const; void add(const Pont& p); void rajzol(); Dinamikus területet ~Poligon() { delete[] pontok; ; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 5 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 6 -

Ismétlés (alakzat) /3 Pont Poligon::getcsp(unsigned int i) const { if (i >= np) throw "Poligon: nincs ilyen"; if (i == 0) return p0; return pontok[i-1] + p0; void Poligon::add(const Pont& p) { Új terület Pont *tp = new Pont[np]; for (unsigned int i = 0; i < np-1; i++) tp[i] = pontok[i]; delete[] pontok; pontok = tp; pontok[np-1] = p - p0; ++np; Pointer az új területre mutat Átmásoljuk az új területre Régi terület felszabadítása Lehet-e tovább általánosítani? Általánosíthatók-e az adatszerkezetek? Már a komplexes első példán is észrevettük, hogy bizonyos adatszerkezetek (pl. tárolók) viselkedése független a tárolt adattól. Lehet pl. adatfüggetlen tömböt vagy listát csinálni? Általánosíthatók-e az algoritmusok? Lehet pl. adatfüggetlen rendezést csinálni? C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 7 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 8 - elemzés: Din. tömb Tároljunk T-ket egy tömbben! Műveletek: Létrehozás/megszüntetés Indexelés Méretet a létrehozáskor (példányosításkor) adjuk Egyszerűség kedvéért nem másolható, nem értékadható és nem ellenőriz indexhatárt! TArray megvalósítás class TArray { unsigned int n; // tömb mérete privát, így nem érhető el T *tp; // elemek tömbjére mutató pointer TArray(const TArray&); // másoló konstr. tiltása TArray& operator=(const TArray&); // tiltás TArray(int n=5) :n(n) { tp = new T[n]; T& operator[](unsigned int i) { return tp[i]; const T& operator[](unsigned inti ) const { return tp[i]; ~TArray() { delete[] tp; ; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 9 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 10 - Mit kell változtatni? Minden T típust át kell írni a kívánt (pl, int, double, Komplex stb.) típusra. T-nek megfefő neveket kellene generálni (nevelem csere) pl: class intarray { unsigned int n; int *tp; intarray(const intarray&);... Más különbség láthatóan nincs. Lehet-e általánosítani? Típusokat és neveket le kell cserélni --> Generikus adatszerkezetek: Olyan osztályok, melyekben az adattagok és a tagfüggvények típusa fordítási időben szabadon paraméterezhető. Megvalósítás: preprocesszorral nem mindig lehetséges, nem típusbiztos nyelvi elemként: template Függvényeknél már használtunk. Miért ne lehetne osztályokra is? C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 11 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 12 -

class Array { unsigned int n; T *tp; Azonosító Osztálysablon // Sablon kezdete Array(int n=5) :n(n) { tp = new T[n];... ; Hatókör vége Array<int> a1, a2, a3; Array<Valami> v1, v2, v3; Formális sablonparamétert lecseréli az akt. paraméterre Array osztály sablonja // osztálysablon class Array { unsigned int n; // tömb mérete T *tp; // elemek tömbjére mutató pointer Array(const Array&); // másoló konstr. tiltása Array& operator=(const Array&); // tiltás Array(int n=5) :n(n) { tp = new T[n]; T& operator[](unsigned int); const T& operator[](unsigned int) const; ~Array() { delete[] tp; ; Sablonparamétertől függő nevet generál (név elem csere) C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 13 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 14 - Array tagfüggvényeinek sablonja // tagfüggvénysablon T& Array<T>::operator[](unsigned int i) { return tp[i]; A scope-hoz a név a paraméterből generálódik template <class T> // tagfüggvénysablon const T& Array<T>::operator[](unsigned int i) const { return tp[i]; Sablonok használata (példányosítás) #include "generic_array.hpp" // sablonok int main() { sablon példányosítása aktuális template paraméterrel Array<int> ia(50), ia1(10); // int array Array<double> da; // double array Array<const char*> ca; // const char* array ia[12] = 4; da[2] = 4.54; ca[2] = "Hello Template"; return 0; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 15 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 16 - Array osztály másként template <class T, unsigned int s> // osztálysablon class fixarray { T t[s]; // elemek tömbje T& operator[](unsigned int i) { if (i >= s) throw "Indexelési hiba"; return t[i]; const T& operator[](unsigned int i) const; ; Többször példányosodik! Növeli a kódot, ugyanakkor egyszerűsödött az osztály. deafault paraméter is lehet template <class T, unsigned int s = 10> // osztálysablon class fixarray { T t[s]; // elemek tömbje T& operator[](unsigned int i) { if (i >= s) throw "Indexelési hiba"; return t[i]; const T& operator[](unsigned int i) const; ; fixarray<int> a10; fixarray<int, 30> a30; fixarray<int, 10> a10; fixarray<int, 30> a30; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 17 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 18 -

Lehet-e tovább általánosítani? Általánosíthatók-e az adatszerkezetek? Sablon Általánosíthatók-e a függvények? Sablon // max példa (ism.) T max(t a, T b) { return a < b? b : a; cout << max(40, 50); cout << max( alma, korte ) // alma const char * Sablon specializáció (ism.) const T& Max(const T& a, const T& b) { return a > b? a : b; // Specilaizáció T::= const char* esetre template <> const char* Max(const char* a,const char* b){ return strcmp(a,b) > 0? a : b; std::cout << Max("Hello", "Adam"); C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 19 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 20 - Részleges és teljes specializáció template <class R, class S, class T> struct A { ; részleges specializálás template <class S, class T> struct A<char, S, T> { ; teljes specializálás template <> struct A<char, char, char>{ ; Sablon specializáció (összef.) Függvények különböző változatai: túlterhelés (overload) Sablonok esetében a túlterhelés mellett egy újabb eszközünk is van: specializáció. Egy sablonnal megadott osztály, vagy függvény adott változatát átdefiniálhatjuk. Ilyenkor nem a sablonban megadott módon fog példányosodni. template <class T> struct V { T a1; V() :a1(t()) { ; V<int>v1; T default konstruktora V<double>v2; template <> struct V<double> { double a1; V() :a1(3.14) { ; v1.a1 0; v2.a1 3.14; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 21 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 22 - Template paraméter típus, konstans, függvény, sablon template <class T1, typename T2, int i = 0> struct V { default T1 a1; T2 a2; int x; V() { x = i; ; V<int, char, 4> v1; V<double, int> v2; // paraméterként kapott típus és konstansa template <typename T, T c = T()> struct V { T val; V() { val = T; ; V<int, 30> v30; v30.val 30; V<double> v0; v0.val 0; Sablon, mint paraméter template <class T> struct Pont { T x, y; ; template <class T> struct Pont3D { T x, y, z; ; template <class S, template <class T> class P = Pont > struct Idom { P<S> origo; // idom origója ; Idom<int> sikidom1; sikidom1.origo Pont<int> Idom<double> sikidom2; sikidom2.origo Pont<double> Idom<int, Pont3D> test; test.origo Pont3D<int> C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 23 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 24 -

Függvénysablonok paraméterei A sablonparaméterek általában levezethetők a függvényparaméterekből. Pl: template<class T> void csere(t& p1, T& p2) { T tmp = p1; p1 = p2; p2 = tmp; int x1 = 1, x2 = 2; csere(x1, x2); Ha nem, akkor meg kell adni. Pl: template<class T, int n> void fv(t t1[n], T t2[n]) { for (int i = n; i >= 0; i--) t1[i] = t2[i]; int it1[10], it2[10]; fv<int, 10>(it1, it2); C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 25 - Mi is a sablon? Típusbiztos nyelvi elem az általánosításhoz. Gyártási forma: a sablonparaméterektől függően példányosodik: osztály vagy függvény (valamilyen dekl.) jön belőle létre. Paraméter: típus, konstans, függvény, sablon, def. A példányok specializálhatók, melyek eltérhetnek az eredeti sablontól. Feldolgozása fordítási idejű ezért a példányosítás helyének és a sablonnak egy fordítási egységben kell lennie. gyakran header fájlba tesszük (.hpp) C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 26 - A feldolgozás fordítási idejű template <int N> struct fakt { enum { fval = N * fakt<n-1>::fval ; ; Specializálás template <> struct fakt<0> { enum { fval = 1 ; ; std::cout << fakt<3>::fval << std::endl; Fordítási időben 4 példány (3,2,1,0) keletkezik Nehéz nyomkövetni, nagyon sok könyvtár (pl. boost) kihasználja. Template metaprogram Algoritmus módosítása Előfordulhat, hogy egy algoritmus (pl. rendezés) működösét módosítani akarjuk egy függvénnyel. Predikátum (ism): Logikai függvény, ami befolyásolja az algoritmus működését. Sablon-, vagy függvényparaméterként egy eljárásmódot (függvényt) is átadhatunk, ami lehet: osztály tagfüggvénye, vagy önálló függvény C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 27 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 28 - Példa: leg... elem kiválasztása template <typename T, class S> T leg1(t a[], int n) { T tmp = a[0]; if (S::select(a[i], tmp)) tmp = a[i]; Az S sablonparaméter egy olyan osztály, melynek van egy select logikai tagfüggvénye, ami az algoritmus működését befolyásolja. pl: struct kisebb_int { static bool select(int a, int b) { return a < b; ; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 29 - Példa: leg... elem kiválasztása /2 // Lehet egy sablonból generálódó osztály is template<typename T> struct nagyobb { // szokásos nagyobb reláció static bool select(t a, T b) { return a > b; ; // Használat: int it[9] = {-5, -4, -3, -2, -1, 0, 1, 2, 3 ; double dt[5] = {.0,.1,.2,.3, 4.4 ; cout << leg1<int, kisebb_int>(it, 9) << endl; // -5 cout << leg1<int, nagyobb<int> >(it, 9) << endl; // 3 cout << leg1<double, nagyobb<double> >(dt, 5); // 4.4 C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 30 -

Problémák, kérdések Megszorítónak tűnik, hogy a tagfüggvényt select-nek hívják. Miért kell az osztály? Így nem lenne jó? template <typename T, bool select(t, T)> T leg2(t a[], int n) { T tmp = a[0]; if (select(a[i], tmp)) tmp = a[i]; template<class T> bool kisebbfv (T a, T b) { return a < b; cout << leg2<int, kisebbfv>(it. 9); Funktor Függvényként használható objektum. template<class T> Funktor osztály struct kisebbobj { (Functor Class) bool operator()(const T& a, const T& b) { return a < b; ; Funktor osztály: függvényként viselkedő osztály. Funktor: Funktor osztály példánya (függvény objektum) C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 31 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 32 - Kettő az egyben? A leg1(...) változat egy osztályt vár, a leg2(...) változat pedig függvényt vár sablon paraméterként. Hogyan lehetne mindkettőt? Kapjon általános típust, és ennek megfelelő példányt kapja meg függvény paraméterként is, amit használjunk függvényként. T legelem(const T a[], int n, S sel) {... if ( sel(...) ) Mindent tudó legelem T legelem(const T a[], int n, S sel) { T tmp = a[0]; if (sel(a[i], tmp)) tmp = a[i]; A függvény második paramétere logikai függvényként viselkedő valami, ami lehet önálló függvény, vagy funktor is. Pl: létre kell hozni cout << legelem<int, kisebbobj<int> > (it, 9, kisebbobj<int>() ); C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 33 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 34 - fixarray és legelem? fixarray<int 100> fixa; // használható igy? legelem(fixa, 100, kisebobj<int>() ); // problémák: T legelem(const T a[], int n, S sel) { T tmp = a[0];... // Elemtípus helyett adjuk át a tömböt: T legelem(const T& a, int n, S sel) { // Rendben, de honnan lesz elem típusunk a tmp-hez? // 1. Adjuk át azt is. // 2. Tegyünk be a fixarray osztályba egy belső típust pl: template <class T, unsigned int s = 10> class fixarray { T t[s]; typedef T value_type;... C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 35 - Mindent tudó legelem /2 // indexelhető tárolókhoz, melynek van value_type belső típusa T legelem(const T& a, int n, S sel) { typename T::value_type tmp = a[0]; if (sel(a[i], tmp)) tmp = a[i]; Segítség a fordítónak // hagyományos tömbökhöz T legelem(const T a[], int n, S sel) { T tmp = a[0]; if (sel(a[i], tmp)) tmp = a[i]; Túlterhelés C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 36 -

Predikátum (összefoglalás) Logikai függvény, vagy függvény-objektum, ami befolyásolja az algoritmus működését Predikátum megadása Sablonparaméterként: template<typename T, bool select(t, T)> T leg2(const T t[], int n); Függvényparaméterként: template<typename T, class F> T legelem(const T t[], int n, F Func); Generikus példa 2 1. Olvassunk be fájl végéig maximum 10 db valamit (pl. valós, komplex, stb. számot)! 2. Írjuk ki! 3. Készítsünk másolatot a tömbről! 4. Rendezzük az egyik példányt nagyság szerint növekvően, a másikat csökkenően! 5. Írjuk ki mindkét tömböt. Gyakoribb, rugalmasabb megadási mód C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 37 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 38 - Példa 2 kidolgozás Van generikus fix méretű tömbünk fixed_size_gen_array.hpp Készítünk generikus rendező algoritmust! generic_sort.hpp Készítünk generikus hasonlító operátorokat! generic_cmp.hpp Készítünk segédsablont a beolvasáshoz és kiíráshoz! Rakjuk össze az építőelemeket! #include <iostream> Példa 2 kidolgozás /2 #include "fixed_size_gen_array.hpp" // fix méretű generikus // tömb indexelhető, másolható, értékadható #include "generic_sort.hpp" // indexelhető típus generikus // rendezése #include "generic_cmp.hpp" // generikus hasonlító függvények // A bemutatott megoldás bármilyen indexelhető típussal, // így pl. az alaptípusokból létrehozott tömbökkel is működik, ha // az elemtípus másolható, értékadható és értelmezett a // <, > <<, és >> művelet. C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 39 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 40 - Példa 2 kidolgozás /2 /// Indexelhető típus elemeit kiírja egy stream-re void CopyToStream(const T& t, int n, std::ostream& os) { for (int i = 0; i < n; ++i) os << t[i] << ","; os << std::endl; /// Indexelhető típus elemeit beolvassa egy stream-ről int ReadFromStream(T& t, unsigned int n, std::istream& is) { unsigned int cnt = 0; while (cnt < n && is >> t[cnt]) cnt++; return cnt; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 41 - Példa 2 kidolgozás /3 int main() { fixarray<double, 10> be; // max. 10 elemű double tömb int db = ReadFromStream(be, 10, std::cin); // beolvasunk CopyToStream(be, db, std::cout); // kiírjuk fixarray<double, 10> masolat = be; // másolat készül insertionsort(be, db, less<double>() ); // növekvő rendezés insertionsort(masolat, db, greater<double>() ); // csökkenő CopyToStream(be, db, std::cout); // kiírjuk az elemeket CopyToStream(masolat, db, std::cout);// kiírjuk az elemeket http://svn.iit.bme.hu/proga2/eloadas_peldak/ea_07/gen_pelda2 C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 42 -

fixed_size_gen_array.hpp #ifndef FIXED_SIZE_GEN_ARRAY_H #define FIXED_SIZE_GEN_ARRAY_H template <class T, unsigned int s> class fixarray { T t[s]; void chkidx(unsigned i) const { if (i >= s) throw "Index hiba"; typedef T value_type; // a példában nem használjuk T& operator[](unsigned int i) { chkidx(i); return t[i]; const T& operator[](unsigned int i) const { chkidx(i); return t[i]; ; #endif C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 43 - generic_sort.hpp #ifndef... void swap(t& a, T& b) { T tmp = a; a = b; b = tmp; template <typename T, class F> void insertionsort (T& a, int n, F cmp) { for (int i = 1; i < n; i++) { int j = i; while (j > 0 && cmp(a[j], a[j-1])) { swap(a[j], a[j-1]); j--; C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 44 - generic_cmp.hpp #ifndef GENERIC_CMP_H #define GENERIC_CMP_H struct less { bool operator()(const T& a, const T& b) const { return a < b; ; struct greater { bool operator()(const T& a, const T& b) const { return a > b; ; #endif C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 45 - Módosítsuk a kiírót! Legyen predikátuma: template <typename T, class F> void CopyToStream(const T& t, int n, std::ostream& os, F fun) { for (int i = 0; i < n; ++i) if (fun(t[i])) os << t[i] << ","; os << std::endl Szeretnénk kiírni elsőször az 5, majd a 15, és a 25- nél nagyobb értékeket. Ennyi predikátumfüggvényt kell készítenünk? C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 46 - Ötlet: a funktor egy objektum // ezért tud tárolni is. Tároljuk le, a referenciaértéket! class greater_than { T ref_value; greater_than(const T& val) : ref_value(val) { bool operator()(const T& a) const { return a > ref_value; ; //Példa: greater_than<int>gt(10); // konstruktor letárolja a 10-et gt(8) // fv. hívás op. false gt(15) // fv. hívás op. true Módosított kiíró használata int main() { int it[9] = {-5, -4, -3, -2, -1, 0, 1, 2, 3 ; CopyToStream(it, 9, std::cout, greater_than<int>(-1) ); // 0,1,2,3, CopyToStream(it, 9, std::cout, greater_than<int>(0) ); // 1,2,3, CopyToStream(it, 9, std::cout, greater_than<int>(1) ); // 2,3, C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 47 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 48 -

Összefoglalás A C-ben megtanult preprocesszor trükkökkel elvileg általánosíthatók az osztályok és függvények, de nem biztonságos, és nem mindig megoldható. template: típusbiztos nyelvi elem az általánosításhoz. Formálisan: template < templ_par_list > declaration Összefoglalás /2 Generikus osztályokkal tovább általánosíthatjuk az adatszerkezeteket: Típust paraméterként adhatunk meg. A generikus osztály később a típusnak megfelelően példányosítható. A specializáció során a sablontól eltérő példány hozható létre Specializáció lehet részleges, vagy teljes C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 49 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 50 - Összefoglalás /3 Generikus függvényekkel tovább általánosíthatjuk az algoritmusokat: Típust paraméterként adhatunk meg. A generikus függvény később a típusnak megfelelően példányosítható. A függvényparaméterekből a konkrét sablonpéldány levezethető, ha nem, akkor explicit módon kell megadni Függvénysablon felüldefiniálható Összefoglalás /4 Predikátumok segítségével megváltoztatható egy algoritmus működése Ez lehetővé teszi olyan generikus algoritmusok írását, mely specializációval testre szabható. Ügyetlen template használat feleslegesen megnövelheti a kódot (pl. széles skálán változó paramétert is template paraméterként adunk át.) C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 51 - C++ programozási nyelv BME-IIT Sz.I. 2018.03.20. - 52 -