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

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

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

Pénzügyi algoritmusok

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

1. Öröklés Rétegelés Nyilvános öröklés - isa reláció Korlátozó öröklődés - has-a reláció

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

Programozás alapjai II. (7. ea) 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:

3. Osztályok II. Programozás II

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

OOP #14 (referencia-elv)

GENERIKUS PROGRAMOZÁS Osztálysablonok, Általános felépítésű függvények, Függvénynevek túlterhelése és. Függvénysablonok

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

128. AA Megoldó Alfréd AA 128.

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

Osztályok. 4. gyakorlat

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

Programozás C++ -ban

Objektumok inicializálása

Programozás C és C++ -ban

117. AA Megoldó Alfréd AA 117.

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

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

Pénzügyi algoritmusok

500. AA Megoldó Alfréd AA 500.

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?

Java II. I A Java programozási nyelv alapelemei

228. AA Default Konstruktor AA 228.

Programozás módszertan

A C++ szigorúbban kezeli a típuseltéréseket, mint a C nyelv Lehetséges típuskonverziók:

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 II. 2. Dr. Iványi Péter

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

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

C++ programozási nyelv Konstruktorok-destruktorok

500. DD Megoldó Alfréd DD 500.

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

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

Programozás C++ -ban 2007/7

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

Programozási Nyelvek: C++

C++ Gyakorlat jegyzet 8. óra

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

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

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

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

Java V. Osztályszint. lyszintű ű tagok. Példányváltozó. Osztályváltozó. Általános Informatikai Tanszék Utolsó módosítás:

Programozás I. 3. gyakorlat. Szegedi Tudományegyetem Természettudományi és Informatikai Kar

Generikus Típusok, Kollekciók

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

500. CC Megoldó Alfréd CC 500.

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

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

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

.AA Megoldó Alfréd AA.

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

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

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

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

503.AA Megoldo Arisztid 503.A

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

Programozás C++ -ban

Pénzügyi algoritmusok

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

500.AJ Megoldó Magyar Magdolna 500.J

Stack Vezérlés szerkezet Adat 2.

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.

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

Apple Swift kurzus 3. gyakorlat

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

A szemantikus elemzés helye. A szemantikus elemzés feladatai. A szemantikus elemzés feladatai. Deklarációk és láthatósági szabályok

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

feladat pont min elért

8. gyakorlat Pointerek, dinamikus memóriakezelés

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

1.AA MEGOLDÓ BERCI AA 1.

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

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

List<String> l1 = new ArrayList<String>(); List<Object> l2 = l1; // error

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

1000.AA Megoldo Alfréd 1000.A

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 C nyelv 7. gyakorlat. Függvények. Függvények(2)

feladat pont min elért

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

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

JAVA PROGRAMOZÁS 2.ELŐADÁS

11. gyakorlat Sturktúrák használata. 1. Definiáljon dátum típust. Olvasson be két dátumot, és határozza meg melyik a régebbi.

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

PROGRAMOZÁSI NYELVEK - CPP. GYAKORLAT JEGYZET

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

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

Java VI. Miskolci Egyetem Általános Informatikai Tanszék. Utolsó módosítás: Ficsor Lajos. Java VI.: Öröklődés JAVA6 / 1

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

és az instanceof operátor

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

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós október 15. Széchenyi István Egyetem, Gy r

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

Átírás:

1. Template (sablon) 1.1. Függvénysablon Maximum függvény megvalósítása függvénynév túlterheléssel. i n l i n e f l o a t Max ( f l o a t a, f l o a t b ) { return a>b? a : b ; i n l i n e double Max ( double a, double b ) { return a>b? a : b ; i n l i n e UT1 Max ( UT1 a, UT1 b ) { return a>b? a : b ; Az unalmas munkát hagyjuk a fordítóra, megvalósítás sablonnal. T Max ( T a, T b ) { return a>b? a : b ; 1.2. Függvénysablon példányosítás Max sablon példányosítása. alapján. double x, y, r e s ; / /... a s s i g n i n g some v a l u e s t o x & y r e s = Max ( x 1,y + 2. 5 ) ; / / Max<double > i n t m = Max ( 5, 1 3 ) ; / / Max<i n t > Sablon paramétert a fordító határozza meg a függvény paraméter típusa Ha nincs függvényparaméter, akkor hogyan lehet példányosítani a függvényt? T any ( void ) { / / r e t u r n a random v a l u e o f t y p e T ; Példányosítás explicit minősítővel. i n t i = any ( ) ; / / Hibás i n t i = any < i n t > ( ) ; / / OK 1.3. Osztálysablon Egyszerű egészeket tartalmazó stack osztály. c l a s s S t a c k { / / i m p l e m e n t a t i o n i n t t o p ; i n t S [ 1 0 0 ] ; / / i n t e r f a c e S t a c k ( ) : t o p ( 1) { void push ( i n t V ) { S[++ t o p ] = V; i n t pop ( void ) { top ; return S [ t o p + 1 ] ; / / o t h e r o p e r a t i o n s... ; 1

Írjunk generikus stack osztályt, tetszőleges típusú adatok tárolására. A T típustól bizonyos operátorokat elvárunk, pl. =. c l a s s S t a c k { / / i m p l e m e n t a t i o n i n t t o p ; T S [ 1 0 0 ] ; / / i n t e r f a c e S t a c k ( ) : t o p ( 1) { void push ( c o n s t T& V ) { S[++ t o p ] = V; T pop ( void ) { top ; return S [ t o p + 1 ] ; / / o t h e r o p e r a t i o n s... ; 1.4. Osztálysablon példányosítása Stack < i n t > i s t k ; Stack <double > d s t k ; Sablon paraméter egész érték is lehet. Adjuk meg a stack méretét sablon paraméteren keresztül. template <typename T, i n t N > c l a s s S t a c k { / / i m p l e m e n t a t i o n i n t t o p ; T S [N ] ; / / i n t e r f a c e S t a c k ( ) : t o p ( 1) { void push ( c o n s t T& V ) { S[++ t o p ] = V; T pop ( void ) { top ; return S [ t o p + 1 ] ; / / o t h e r o p e r a t i o n s... ; Stack < s t r i n g, 100> s s t k ; 1.5. sablonok definiálása Szokásos sablon definiálás. template <typename T> c l a s s C { C ( ) {... / / k o n s t r u k t o r név nem t í p u s ~C ( ) {... / / d e s t r u k t o r void f ( ) {... / / member f u n c t i o n ; 2

Sablon definiálás teljes formában template <typename T> c l a s s C { C<T > ( ) {... / / k o n s t r u k t o r ~C<T > ( ) {... / / d e s t r u k t o r void f ( ) {... / / member f u n c t i o n ; Hatványozó függvénysablon: template < unsigned N, typename T > T Power ( c o n s t T& v ) { T r e s = v ; f o r ( i n t i =1; i <N; i ++ ) r e s *= v ; return r e s ; void f ( ) { double d1 = Power < 5 > ( 1. 2 ) ; double d2 = Power <5, i n t > ( 1. 2 ) ; s t d : : c o u t << d1 << " " << d2 ; 1.6. Függvénysablon specializáció template < c l a s s T> bool cmp ( T c o n s t& a, T c o n s t& b ) { return a < b ; template < c l a s s T> bool cmp ( T* c o n s t& a, T* c o n s t& b ) { return * a < *b ; bool cmp ( c o n s t char * a, c o n s t char * b ) { return strcmp ( a, b ) <0; Faktoriális kiszámítása fordítási időben sablon felhasználásával. Nem biztos, hogy hasznos, de jó példa a specializálásra. template < unsigned N> unsigned long F a c t ( void ) { return N* Fact <N 1 >(); template <> unsigned long Fact <0 >( void ) { return 1 ; 1.7. Osztálysablon specializáció c l a s s C { / / common i m p l e m e n t a t i o n c l a s s C<T*> { / / i m p l e m e n t a t i o n f o r t h e s p e c i f i e d s u b s e t 3

1.8. Sablon paraméterek lehetséges specializálása const T konstans típus T* pointer T& hivatkozás (referencia) T[integer-constant] tömb type (*)(T) T típusú argumentummal rendelkező függvénypointer. T(*)() T visszatérési értékkel rendelkező függvénypointer. T(*)(T) T típusú argumentummal és visszatérési értékkel rendelkező függvénypointer. 1.9. Typename kulcsszó használata void f ( ) { typename T : : t 1 * m2 ; / / d e c l a r a t i o n T : : t 2 * m3 ; / / e x p r e s s i o n 1.10. Függvény objektum template <typename T> c l a s s G r e a t e r { T v a l u e ; G r e a t e r ( c o n s t T& v ) : v a l u e ( v ) { bool operator ( ) ( c o n s t T& x ) c o n s t { return x> v a l u e ; / / i n l i n e ; template < typename T, typename Comparator > T* f i n d ( T* pool, i n t n, c o n s t Comparator& comp ) { T* p = pool ; f o r ( i n t i = 0 ; i <n ; i ++ ) { i f ( comp (* p ) ) return p ; / / s u c c e s s p ++; return 0 ; / / f a i l double A[ 1 0 0 ] ; double * p = f i n d (A, 100, G r e a t e r <double > ( 5 ) ) ; 4

1.11. Alapadatok inicializálása template < template <typename, i n t > c l a s s Tomb, typename T, i n t N > o s t r e a m& operator < <( o s t r e a m& os, c o n s t Tomb<T, N>& t t ) { f o r ( i n t i =0; i <N; i ++) cout << t t. t [ i ] << ; return os ; template < c l a s s T, i n t N> c l a s s Tomb { T t [N ] ; Tomb ( ) { f o r ( i n t i = 0 ; i < N; i ++) t [ i ] = T ( ) ; / / G e n e r i k u s d e f a u l t. A l a p t í p u s o k n á l 0 T& operator [ ] ( i n t i ) { i f ( i < 0 i >= N) throw "Index hiba" ; return t [ i ] ; f r i e n d o s t r e a m& operator << <>( o s t r e a m& os, c o n s t Tomb<T, N>& t t ) ; ; Figyeljük meg az ostream& operator<< <>(...) deklarációjánál a <> üres template paramétert. Mivel a barát függvényt függvénysablonból állítjuk elő, ezért ezt jelezni kell. Ha a függvény paraméterből a fordító következtetni tud a sablon paraméterre, akkor a sablon paraméter lehet üres is. Ha nem írjuk ki, akkor a fordító automatikusan nem példányosítja a barát operátort és linkelési hiba keletkezik. A Tomb() konstruktorban a t[i] = T() értékadás a beépített típusokat inicializálja. Ha ez nincs, és int típusú adatokat tárolunk a tömbbe, akkor az elemek értéke nem meghatározott. Osztályok esetén viszont a tömb elemeit kétszer inicializáljuk. Hogyan lehet ezt elkerülni? Módosítsuk a konstruktort a következő módon: template < c l a s s T, i n t N> c l a s s Tomb { T t [N ] ; Tomb ( ) { i f (! I s C l a s s T <T > : : Yes ) { f o r ( i n t i = 0 ; i < N; i ++) t [ i ] = T ( ) ; / / G e n e r i k u s d e f a u l t. A l a p t í p u s o k n á l 0....... Írjuk meg a IsClassT<T> osztálysablont. template < typename T> c l a s s I s C l a s s T { template < c l a s s X> s t a t i c char T e s t ( i n t X: : * ) ; template < c l a s s X> s t a t i c long T e s t (... ) ; enum { Yes = s i z e o f ( I s C l a s s T <T > : : Test <T>( 0 ) ) == 1 ; enum { No =! Yes ; ; 5

A megoldáshoz részleges tagfüggvénysablon specializálást használhatunk. A Test() függvény különböző méretű adatot ad vissza, annak a függvényében, hogy milyen paraméterrel hívjuk. :: tagválasztó operátora csak osztályoknak (struktúráknak) lehet. A Test(int X::* ) egész tagváltozóra mutató pointert vár. Egyébként a Test(...) függvény játszik szerepet. Az IsClassT<T>::Test<T>(0) paramétere trükkösen 0, ami lehet egy memóriacím érték, de illeszkedik a változó függvényparaméter listára is. Ha a T sablon paraméter class, akkor a char Test(int X::*) függvényt generálja ki a fordító. A sizeof() operátor fordítási időben értékelődik ki, tehát csak az fontos, hogy a T sablon paraméterrel melyik tagfüggvényt példányosítja a fordító, de a függvény futási időben nem hívódik meg. Ezért a Test() függvényeket csak deklaráltuk, és nem definiáltuk. Akkor is a char Test(int X::*) függvényt példányosítja a fordító, ha olyan osztállyal példányosítjuk a sablont, aminek egyetlen tagváltozója sincs. Sajnos ezt a szép megoldást az általunk ismert fordítók nem értik, fordítási hiba keletkezik. Az IsClassTHelper belső struktúra bevezetésével azonban elegendő segítséget kapnak a fordítók, így már megbírkoznak a feladattal Az IsClassT template a www.hit.bme.hu/ izso/modtomb.cpp példaprogram segítségével tesztelhető. template <typename T> c l a s s I s C l a s s T { s t r u c t I s C l a s s T H e l p e r { template <typename X> s t a t i c char T e s t ( i n t X: : * ) ; template <typename X> s t a t i c long T e s t (... ) ; ; t y p e d e f I s C l a s s T H e l p e r H; enum { Yes = s i z e o f ( H : : template Test <T>( 0 ) ) == s i z e o f ( char ) ; enum { No =! Yes ; ; 6

Írjunk osztálysablont, ami eldönti, hogy az első paramétere konvertálható-e a második paraméterre. template < c l a s s T, c l a s s U> c l a s s C o n v e r s i o n { t y p e d e f char Small ; s t r u c t Big { char dummy [ 4 ] ; ; s t a t i c Small T e s t (U ) ; s t a t i c Big T e s t (... ) ; s t a t i c T MakeT ( ) ; enum{ e x i s t s = s i z e o f ( T e s t ( MakeT ( ) ))== s i z e o f ( Small ) ; ; 7