Függvénysablonok használata Különböző függvények hasonló feldolgozás különböző adattípusok
Sablonok definíciója A sablonok egy utasításhalmazt definiálnak, amellyel programjaink később további függvényeket hozhatnak létre.
Sablonok használata két vagy több függvény gyors definiálására valók, melyek hasonló utasításokkal, de különböző paraméterekkel, vagy visszaadott értéktípussal dolgoznak.
Sablonok feldolgozása A C++ fordító létrehozza a függvényeket a sablon nevére utaló prototípusokban megadott típusokkal.
max függvény sablonja template<class T> T max ( T a, T b) { template<class T> T max ( T a, T b) { if (a > b ) return (a); else return (b); }
Sablonok tulajdonságai A T a sablon általános típusa. Prototípusokat kell deklarálnunk az egyes típusokhoz: float max(float, float); int max (int, int)
Főprogram: { cout << "A 100 és 200 közül a nagyobb: "<< max (100, 200) << endl; cout << "Az 5.123 és 1.200 közül a nagyobb: " << max (5.123, 1.200) << endl; }
A teljes program #include <iostream.h> template<class T> T max ( T a, T b) { if (a > b ) return (a); else return (b); } float max(float, float); int max (int, int);
A teljes program folytatása void main() { cout << "A 100 ‚s 200 közül a nagyobb: "<< max (100, 200) << endl; cout << "Az 5.123 ‚s 1.2 közül a nagyobb: "<< max (5.123, 1.2) << endl; }
Osztálysablonok használata A template kulcsszó segítségével létrehozhatunk osztálysablonokat, amelyeket az osztálydefiníció használhat adattagok, és tagfüggvények visszaadott értékeinek valamint paraméterértékek típusainak megadására.
tomb osztály létrehozása #include <iostream.h> #include <stdlib.h> class tomb { public: tomb (int meret); long osszeg ( void); int atlag_ertek(void); void tomb_kiiras(void); int ertek_hozzaadas(int); private: int *adatok; int meret; int index; };
Metódusok definiálása tomb:: tomb(int meret) { adatok = new int [meret]; if (adatok == NULL) cerr <<"Keves a memoria -- a program befejezodik" << endl; exit(1); } tomb::meret = meret; tomb::index = 0;
Metódusok definiálása long tomb::osszeg(void) { long osszeg = 0; int i; for (i=0; i<index; i++) osszeg += adatok[i]; return (osszeg); }
Metódusok definiálása int tomb::atlag_ertek(void) { long osszeg = 0; int i; for (i=0; i<index; i++) osszeg += adatok[i]; return (osszeg/index); }
Metódusok definiálása void tomb::tomb_kiiras(void) { int i; for (i=0; i<index; i++) cout<< adatok[i]<<' '; cout<< endl; }
Metódusok definiálása int tomb::ertek_hozzaadas(int ertek) { if (index== meret) return(-1) else adatok[index] = ertek; index++; return(0); }
Főprogram void main(void) { tomb szamok(100); int i; for(i = 0; i<50; i++) szamok.ertek_hozzaadas(); szamok.tomb_kiiras(); cout<<"A szamok osszege: "<<szamok.osszeg() <<endl; cout<<"Az atlagertek: "<<szamok.atlag_ertek() <<endl; }
Az előző feladat sablonnal #include <iostream.h> #include <stdlib.h> template<class T, class T1> class tomb { public: tomb (int meret); T1 osszeg ( void); T atlag_ertek(void); void tomb_kiiras(void); int ertek_hozzaadas(T); private: T *adatok; int meret; int index; };
Metódusok definiálása template<class T,class T1> tomb<T,T1>:: tomb(int meret) { adatok = new T [meret]; if (adatok == NULL) cerr <<"Keves a memoria -- a program befejezodik" << endl; exit(1); } tomb::meret = meret; tomb::index = 0;
Metódusok definiálása template<class T,class T1> T1 tomb<T,T1>::osszeg(void) { T1 osszeg = 0; int i; for (i=0; i<index; i++) osszeg += adatok[i]; return (osszeg); }
Metódusok definiálása template<class T,class T1> T tomb<T,T1>::atlag_ertek(void) { T1 osszeg = 0; int i; for (i=0; i<index; i++) osszeg += adatok[i]; return (osszeg/index); }
Metódusok definiálása template<class T,class T1> void tomb<T,T1>::tomb_kiiras(void) { int i; for (i=0; i<index; i++) cout<< adatok[i]<<' '; cout<< endl; }
Metódusok definiálása template<class T,class T1> int tomb<T,T1>::ertek_hozzaadas(T ertek) { if (index== meret) return(-1) else adatok[index] = ertek; index++; return(0); }
Főprogram void main(void) { tomb<int, long> szamok(100); // 100 elemes tomb tomb<float, float> ertekek(200); // 200 elemes tomb int i; for(i = 0; i<50; i++) szamok.tomb_kiiras(); cout<<"A szamok osszege: "<<szamok.osszeg() <<endl; szamok.ertek_hozzaadas(i); cout<<"Az atlagertek: "<<szamok.atlag_ertek() <<endl;
Főprogram folytatása for(i = 0; i<100; i++) for(i = 0; i<100; i++) ertekek.ertek_hozzaadas( i * 100); ertekek.tomb_kiiras(); cout<<"A szamok osszege: "<<ertekek.osszeg() <<endl; cout<<"Az atlagertek: "<<ertekek.atlag_ertek() <<endl; }
Osztálysablon létrehozásához az osztálydefiníció elé tegyük a template kulcsszót és a típusszimbólumokat, például T és T1. Mindegyik osztályfüggvény definíciója elé ugyanezt a template utasítást kell tennünk. Ezenkívül osztály_ név < T, T1> :: függvény_nev
Objektumok létrehozása osztálysablonnal sablon osztaly_nev< típus1, típus2> objektum_nev ( par1, par2) Például: tomb<char, int> kis_szamok(100)
Student osztály #include <iostream.h> #include <string.h> enum BOOL { FALSE, TRUE } ; class Student { char name[30]; double average; public: Student (char *n =NULL, double a = 0.0 ) { strcpy(name,n); average = a;} double Average() { return average;} void Set (char *n, double a ) { strcpy(name,n);average = a;} char* GetNev(){return name;} double GetAtlag () {return average;} };
StudentListElem osztály class StudentList; class StudentListElem { friend class StudentList; Student data; StudentListElem *next; public: StudentListElem (){} StudentListElem (Student d, StudentListElem *n) { data =d; next = n;} };
StudentList class StudentList { StudentListElem head, *current; int Compare (Student& d1, Student& d2) {return (d1.Average() > d2.Average() ) ; } public: StudentList() { current = &head; head.next =0; } void Insert (Student&); BOOL Get (Student&); };
Metódusok definiálása void StudentList :: Insert (Student& data) { for (StudentListElem* p =&head; p->next !=NULL; p=p->next) if (Compare (p-> data, data) ) break; StudentListElem* old = new StudentListElem ( p->data, p->next); p->data = data; p->next = old; }
Metódusok definiálása BOOL StudentList:: Get (Student& e) { if(current->next == NULL ) { current = &head; return FALSE; } e = current ->data; current = current->next; return TRUE;
Főprogram main() { StudentList list; Student st; char nev[30]; double atlag; char cont; double average = 0; int nstudent = 0;
Főprogram folytatása do { cout << "\nName: "; cin >> nev; cout << "\nAverage: "; cin >> atlag; st.Set(nev,atlag); list.Insert( st ); nstudent++; average += atlag; cout << "\nMore Students? (y/n)"; cin >> cont; } while ( cont == 'y' );
Főprogram folytatása average /= nstudent; while ( list.Get( st ) ) { while ( list.Get( st ) ) { if (st.GetAtlag() >= average) cout << st.GetNev() << " " << st.GetAtlag() << "\n"; }
List osztály template-tel #include <iostream.h> #include <process.h> enum BOOL { FALSE, TRUE }; // GENERIC LIST TYPE template<class R> class List;
ListElem template <class T> class ListElem { friend class List<T>; T data; ListElem * next; public: ListElem( ) { } ListElem( T d, ListElem * n) { data = d; next = n; } };
List template <class R> class List { ListElem<R> head, *read_ptr; public: List( ) { head.next = NULL; read_ptr = &head; } void Insert( R& data ); // insert into the list BOOL Get( R& data ); // get next from the list, ret==IsEND void Select( int index ); // select for the next Get virtual int Compare( R& d1, R& d2 ) { return 1; } };
Metódusok definiálása template <class R> void List<R> :: Insert ( R& data ) { for( ListElem<R> *p = &head; p->next != NULL; p = p->next ) { if ( Compare( p->data, data) == 1 ) break; } ListElem<R> *old = new ListElem<R>( p->data, p->next); p->data = data; p->next = old;
Metódusok definiálása template <class R> BOOL List<R> :: Get ( R& data ) { if ( read_ptr -> next == NULL ) { // end of list read_ptr = &head; return FALSE; } else { // not end, step to next data = read_ptr -> data; read_ptr = read_ptr -> next; return TRUE; }
Metódusok definiálása /*template <class R> void List<R> :: Select ( int index ) { read_ptr = &head; if (index == 0) { if ( read_ptr->next == NULL) cerr << "Invalid Select in List"; }else { for( int i = 0; i < index; i++ ) { read_ptr = read_ptr->next; }
Student template-tel #include "templ11.cpp" struct Student { #include "templ11.cpp" struct Student { char name[20]; int year; double average; };
Főprogram void main() { Student st; List<Student> list; char cont; double average = 0; int nstudent = 0;
Főprogram folytatása do { cout << "\nName: "; cin >> st.name; cout << "\nYear: "; cin >> st.year; cout << "\nAverage: ";cin>> st.average; list.Insert( st ); nstudent++; average += st.average; cout << "\nMore Students? (y/n)"; cin >> cont; } while ( cont == 'y' );
Főprogram folytatása average /= nstudent; while ( list.Get( st ) ) { while ( list.Get( st ) ) { if (st.average >= average) cout << st.name << " " << st.average << "\n"; }