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

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

117. AA Megoldó Alfréd AA 117.

3. Osztályok II. Programozás II

128. AA Megoldó Alfréd AA 128.

.AA Megoldó Alfréd AA.

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

1.AA MEGOLDÓ BERCI AA 1.

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

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)

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

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

500. AA Megoldó Alfréd AA 500.

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) {} };

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

500. CC Megoldó Alfréd CC 500.

1000.AA Megoldo Alfréd 1000.A

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

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á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)

C++ Gyakorlat jegyzet 8. óra

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

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

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

Osztály és objektum fogalma

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)

C++ programozási nyelv Konstruktorok-destruktorok

503.AA Megoldo Arisztid 503.A

1. Alapok. Programozás II

228. AA Default Konstruktor AA 228.

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

Alprogramok, paraméterátadás

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

500.AJ Megoldó Magyar Magdolna 500.J

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

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

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

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

C++ Standard Template Library (STL)

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

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

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

Pénzügyi algoritmusok

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

Fejlett programozási nyelvek C++ Iterátorok

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

500.AA Megoldó Kulcsár 500.A

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

Objektumok inicializálása

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)

500.AA Megoldo Arisztid 500.A

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

Programozás C++ -ban 2007/4

500. DD Megoldó Alfréd DD 500.

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

Osztályok. 4. gyakorlat

Bevezetés a programozásba 2

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

feladat pont min elért

Programozási Nyelvek: C++

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

feladat pont min elért

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

Programozás C++ -ban

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

Pénzügyi algoritmusok

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

Java és web programozás

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

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

Programozás C++ -ban

Programozás II gyakorlat. 6. Polimorfizmus

Pénzügyi algoritmusok

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

Programozás módszertan

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

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

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

Objektum elvű alkalmazások fejlesztése. Verem típus osztály-sablonja

Virtuális függvények (late binding)

AA MEGOLDÓ ALADÁR AA

Java és web programozás

Programozási nyelvek Java

Objektum elvű alkalmazások fejlesztése Programozási tételek újrafelhasználása 1. Készítette: Gregorics Tibor

111. AA Megoldó Alfréd AA 111.

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

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

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

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

C++ programozási nyelv

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.

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

Programozás alapjai II. (5. ea) C++ Objektummodell, öröklés, virtuális tagfüggvény

Átírás:

Programozás alapjai II. (7. ea) C++ generikus szerkezetek, template újból 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. 2019.03.26. - 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. 2019.03.26. - 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 C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 3 -

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. 2019.03.26. - 4 -

Ismétlés (alakzat) class Alakzat { protected: Pont p0; ///< alakzat origója Szin sz; ///< alakzat színe public: }; 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 Tartalmazott objektumok Virtuális rajzol. Leszármazottban valósul meg. C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 5 -

Ismétlés (alakzat) /2 class Poligon : public Alakzat { size_t np; Pont *pontok; Poligon(const Poligon&); Ős inicializálása Poligon& operator=(const Poligon&); public: Poligon(const Pont& p0, const Szin sz) :Alakzat(p0, sz), np(1), pontok(new Pont[np-1] {} int getnp() const { return np; } Pont getcsp(size_t i) const; void add(const Pont& p); void rajzol(); ~Poligon() { delete[] pontok; } }; Ne legyen használható Dinamikus területet C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 6 -

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. 2019.03.26. - 7 -

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! C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 8 -

TArray megvalósítás class TArray { size_t n; // tömb mérete T *tp; // elemek tömbjére mutató pointer TArray(const TArray&); // másoló konstr. tiltása TArray& operator=(const TArray&); // tiltás public: }; TArray(size_t n=5) :n(n) { tp = new T[n]; } T& operator[](size_t i) { return tp[i]; } privát, így nem érhető el const T& operator[](size_t i) const { return tp[i]; } ~TArray() { delete[] tp; } C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 9 -

Mit kell változtatni? Minden T típust át kell írni a kívánt (pl, int, double, Komplex stb.) típusra. T-nek megfelelő neveket kellene generálni (név elem csere) pl.: class intarray { size_t n; int *tp; intarray(const intarray&);... Más különbség láthatóan nincs. C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 10 -

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. 2019.03.26. - 11 -

Osztálysablon template <typename T> // Sablon kezdete class Array { size_t n; T *tp; Azonosító public: }; Formális sablonparamétert lecseréli az akt. paraméterre Array(size_t n=5) :n(n) { tp = new T[n]; }... Aktuális sablonparaméter Hatókör vége Array<int> a1, a2, a3; Array<Valami> v1, v2, v3; C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 12 -

Array osztály sablonja template <typename T> // osztálysablon class Array { size_t 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 public: Array(size_t n=5) :n(n) { tp = new T[n]; } T& operator[](size_t); const T& operator[](size_t) const; ~Array() { delete[] tp; } }; Sablonparamétertől függő nevet generál (név elem csere) C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 13 -

Array tagfüggvényeinek sablonja template <typename T> T& Array<T>::operator[](size_t i) { return tp[i]; } // tagfüggvénysablon A scope-hoz a név a paraméterből generálódik template <class T> // tagfüggvénysablon const T& Array<T>::operator[](size_t i) const { return tp[i]; } C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 14 -

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. 2019.03.26. - 15 -

Array osztály másként template <class T, unsigned int s> // osztálysablon class fixarray { T t[s]; // elemek tömbje public: T& operator[](size_t i) { if (i >= s) throw "Indexelési hiba"; return t[i]; } const T& operator[](size_t i) const; }; Többször példányosodik! Növeli a kódot, ugyanakkor egyszerűsödött az osztály. fixarray<int, 10> a10; fixarray<int, 30> a30; C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 16 -

deafault paraméter is lehet template <class T, unsigned int s = 10> // osztálysablon class fixarray { T t[s]; // elemek tömbje public: T& operator[](size_t i) { if (i >= s) throw "Indexelési hiba"; return t[i]; } const T& operator[](size_t i) const; }; fixarray<int> a10; fixarray<int, 30> a30; C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 17 -

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.) template <typename T> T max(t a, T b) { return a < b? b : a; } cout << max(40, 50); cout << max( alma, korte ); // alma const char * C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 18 -

Sablon specializáció (ism.) template <typename T> 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. 2019.03.26. - 19 -

Részleges és teljes specializáció template <class R, class S, class T> struct A { }; template <class S, class T> struct A<char, S, T> { }; részleges specializálás teljes specializálás template <> struct A<char, char, char>{ }; C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 20 -

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()) { } }; T default konstruktora template <> struct V<double> { double a1; V() :a1(3.14) { } }; V<int>v1; V<double>v2; v1.a1 0; v2.a1 3.14; C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 21 -

Template paraméter típus, konstans, függvény, sablon template <class T1, typename T2, int i = 0> struct V { T1 a1; T2 a2; int x; V() { x = i;} }; default V<int, char, 4> v1; V<double, int> v2; // paraméterként kapott típus és konstansa, ami // csak integrális, vagy pointer típus lehet template <typename T, T c = T()> struct V1 { T val; V1() { val = c;} }; V1<int, 30> v30; // v30.val 30; V1<int*> v0; // v0.val NULL; C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 22 -

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; Idom<double> sikidom2; sikidom2.origo; Idom<int, Pont3D> test; test.origo; Pont<int> Pont<double> Pont3D<int> C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 23 -

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. 2019.03.26. - 24 -

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. 2019.03.26. - 25 -

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 }; }; Template metaprogram 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, de nagyon sok könyvtár (pl. boost) használja. C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 26 -

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. 2019.03.26. - 27 -

Példa: leg... elem kiválasztása template <typename T, class S> T leg1(t a[], int n) { T tmp = a[0]; for (int i = 1; i < n; ++i) if (S::select(a[i], tmp)) tmp = a[i]; return tmp; } 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. 2019.03.26. - 28 -

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. 2019.03.26. - 29 -

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]; for (int i = 1; i < n; ++i) if (select(a[i], tmp)) tmp = a[i]; return tmp; } template<class T> bool kisebbfv (T a, T b) { return a < b; } cout << leg2<int, kisebbfv>(it. 9); C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 30 -

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. 2019.03.26. - 31 -

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. template <typename T, typename S> T legelem(const T a[], int n, S sel) {... if ( sel(...) ) C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 32 -

Mindent tudó legelem template <typename T, typename S> T legelem(const T a[], int n, S sel) { T tmp = a[0]; for (int i = 1; i < n; ++i) if (sel(a[i], tmp)) tmp = a[i]; return tmp; } 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: cout << legelem<int, kisebbobj<int> > (it, 9, kisebbobj<int>() ); létre kell hozni C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 33 -

fixarray és legelem? fixarray<int 100> fixa; // használható igy? legelem(fixa, 100, kisebobj<int>() ); // problémák: template <typename T, typename S> T legelem(const T a[], int n, S sel) { T tmp = a[0];... // Elemtípus helyett adjuk át a tömböt: template <typename T, typename S> 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]; public: typedef T value_type;... C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 34 -

Mindent tudó legelem /2 // indexelhető tárolókhoz, melynek van value_type belső típusa template <typename T, typename S> T legelem(const T& a, int n, S sel) { typename T::value_type tmp = a[0]; for (int i = 1; i < n; ++i) if (sel(a[i], tmp)) tmp = a[i]; return tmp; } Segítség a fordítónak // hagyományos tömbökhöz template <typename T, typename S> T legelem(const T a[], int n, S sel) { T tmp = a[0]; for (int i = 1; i < n; ++i) if (sel(a[i], tmp)) tmp = a[i]; return tmp; } Túlterhelés C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 35 -

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); Gyakoribb, rugalmasabb megadási mód C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 36 -

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. C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 37 -

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! C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 38 -

Példa 2 kidolgozás /2 #include <iostream> #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. 2019.03.26. - 39 -

Példa 2 kidolgozás /2 /// Indexelhető típus elemeit kiírja egy stream-re template <typename T> void CopyToStream(const T& t, size_t n, std::ostream& os) { for (size_t i = 0; i < n; ++i) os << t[i] << ","; os << std::endl; } /// Indexelhető típus elemeit beolvassa egy stream-ről template <typename T> int ReadFromStream(T& t, size_t n, std::istream& is) { size_t cnt = 0; while (cnt < n && is >> t[cnt]) cnt++; return cnt; } C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 40 -

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://git.ik.bme.hu/prog2/eloadas_peldak/ea_07 gen_pelda2 C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 41 -

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 "hiba"; } public: typedef T value_type; // a példában nem használjuk T& operator[](size_t i) { chkidx(i); return t[i]; } const T& operator[](size_t i) const { chkidx(i); return t[i]; } }; #endif C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 42 -

generic_sort.hpp #ifndef... template <typename T> void swap(t& a, T& b) { T tmp = a; a = b; b = tmp; } template <typename T, class F> void insertionsort (T& a size_t n, F cmp) { for (size_t i = 1; i < n; i++) { size_t 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. 2019.03.26. - 43 -

generic_cmp.hpp #ifndef GENERIC_CMP_H #define GENERIC_CMP_H template <typename T> struct less { bool operator()(const T& a, const T& b) const { return a < b; } }; template <typename T> struct greater { bool operator()(const T& a, const T& b) const { return a > b; } }; #endif C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 44 -

Módosítsuk a kiírót! Legyen predikátuma: template <typename T, class F> void CopyToStream(const T& t, size_t n, std::ostream& os, F fun) { for (size_t 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. 2019.03.26. - 45 -

Ötlet: tároljon egy ref. értéket template <typename T> class greater_than { T ref_value; public: 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 C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 46 -

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. 2019.03.26. - 47 -

Ö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 C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 48 -

Ö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. 2019.03.26. - 49 -

Ö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ó C++ programozási nyelv BME-IIT Sz.I. 2019.03.26. - 50 -

Ö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. 2019.03.26. - 51 -