Programowanie 2. Język C++. Wykład 10. 1 10.1 Szablony
Transkrypt
Programowanie 2. Język C++. Wykład 10. 1 10.1 Szablony
Programowanie 2. Język C++. Wykład 10.
10.1
10.2
10.3
10.4
10.1
Szablony ................................................................................................................................................ 1
Szablony funkcji ...................................................................................................................................... 2
Szablony klas ......................................................................................................................................... 5
Szablony jako wstęp do biblioteki STL .................................................................................................. 10
Szablony
Szablony definiują sparametryzowane rodziny klas, funkcji.
Szablony deklarujemy i definiujemy za pomocą słowa kluczowego template.
Składnia polecenia template:
template < parametry_szablonu > definicja_szablonu
Zastosowania szablonów:
•
definicja funkcji, które mogą operować na dowolnych typach danych, tzn. argumenty funkcji i zwracany typ
moŜe być dowolnego typu,
•
definicja klas, struktur, tablic mogących przechowywać róŜne typy danych.
Przykład 1. Składnia szablonu klasy z jednym parametrem.
template<class T> class NazwaKlasy {
};
Przykład 2. Składnia szablonu funkcji.
template<parametry szablonu> zwracanyTyp nazwaFunkcji(lista argumentów) { }
template<class T> T nazwaFunkcji(T t) { return t;
}
Słowo kluczowe class, oznacza typ parametru szablonu.
Typ class moŜna zamienić dowolnym typem danych lub słowem kluczowym typename.
1
Programowanie 2. Język C++. Wykład 10.
10.2
Szablony funkcji
Szablon funkcji definiuje sparametryzowaną rodzinę funkcji.
Przykład 1. Składnia szablonu funkcji.
template<parametry szablonu> zwracanyTyp nazwaFunkcji(lista argumentów) { }
Przykład 2. Funkcja MAX(int, int) zwraca liczbę większą, typu int.
Szablon funkcji maxx(const T&, const T&)zwraca liczbę większą dowolnego typu
(w10-01-template-funMax.cpp).
template <class NazwaTypu> NazwaTypu maxx(NazwaTypu x, NazwaTypu y)
{
return (x > y) ? y : x;
};
#include <iostream>
using namespace std;
inline int MAX(int a, int b) { return a > b ? a : b; }
template<class T>
inline const T& maxx(const T& a, const T& b)
{
return a > b ? a : b;
}
void main ()
{
double a, b, c;
int x = 10, y = 20, z;
a = 8.33;
b = 7.99;
c = maxx(a,b);
cout << c << endl;
z = maxx(x,y);
cout << z << endl;
z = MAX(x,y);
cout << z << endl;
}
2
Programowanie 2. Język C++. Wykład 10.
Przykład 3. Definicja szablonu funkcji.
Do szablonu funkcji moŜna przekazywać wartości o róŜnych typach (w10-02-template-argFunkcji.cpp)
#include <iostream>
using namespace std ;
template < class tT >
tT Funkcja( const tT& );
int Funkcja( const int& ri ) {
cout << "Funkcja( const int&) " << endl;
return ri;
}
double Funkcja( const double & rd ) {
cout << "Funkcja( const float&)" << endl;
return rd;
}
void main()
{
const int ci = 99;
const double cd = 3.14;
const char cCh= 'A';
Funkcja(ci);
Funkcja(cd);
Funkcja(cCh);
}
template < class tT >
tT Funkcja( const tT& rt )
{
cout << "Funkcja( const tT&)" << endl;
return rt;
}
3
Programowanie 2. Język C++. Wykład 10.
Przykład 4. Definicja szablonu funkcji.
Do szablonu funkcji moŜna przekazywać referencje lub wskaźniki róŜnych typów
(w10-03-template-argFunkcji.cpp)
#include <iostream>
using namespace std;
template<typename T>
T ftr(const T &x)
{
cout << "\n ftr(const T &)
return x;
}
template<typename T>
T ftp(const T *pz)
{
cout << "\n ftp(const T *)
return *pz;
}
static char f(const char &rc)
{
cout << "\n f(const char &)
return rc;
}
static char f(const char *pch)
{
cout << "\n f(const char *)
return *pch;
}
=
=
";
=
";
=
";
";
void main()
{
char c = 'A';
char *pc = &c;
cout
cout
cout
cout
cout
<<
<<
<<
<<
<<
ftr(c);
ftp(pc);
f(c);
f(pc);
"\n";
double d = 3.14;
double *pd = &d;
cout << ftr(d);
cout << ftp(pd);
cout << "\n";
}
4
Programowanie 2. Język C++. Wykład 10.
10.3
Szablony klas
Szablony klasy definiuje sparametryzowaną rodzinę klas.
Przykład 1. Składnia szablonu klasy.
template<class T> class NazwaKlasy {
};
Przykład 2. Definicja szablonu klasy.
Konstruktor, destruktor klasy zdefiniowany jest poza klasą (w10-04-template-klasa.cpp).
#include <iostream>
using namespace std;
template <class t> class A
{
public:
A();
~A();
};
template <class t> A<t>::A(){ cout << "A()" << endl; }
template <class t> A<t>::~A(){cout << "~A()" << endl; }
void main()
{
A<int> ai ;
A<double> ad ;
}
Przykład 3. Definicja szablonu klasy.
Typ atrybutu klasy zaleŜy deklaracji obiektu (w10-05-template-atrybutTypuIntDouble.cpp).
#include <iostream>
using namespace std;
template <class T>
class A
{
public:
A() { cout << "A()" << endl;} ;
~A() { cout << "~A()" << endl;} ;
T x;
};
void main()
{
A<int> ai; //tworzenie obiektu typu A<int>
ai.x = 99;
// ai.x = 3.14; // błąd, conversion from 'double' to 'int'
A<double> ad; //tworzenie obiektu typu A<double>
ad.x = 3.14;
// ad.x = "3,14"; // błąd, cannot convert from 'const char [5]' to 'double'
}
5
Programowanie 2. Język C++. Wykład 10.
Przykład 4. Szablon struktury, sparametryzowany zbiór struktur (w10-06-template-getSet.cpp).
#include <iostream>
using namespace std;
template<class T>
struct W
{
private:
T* in;
public:
void set(T* x){ in = x;}
T get() {
cout << "get(), in=
return *in;
}
};
void
{
";
main()
W<double> w;
double d = 3.14;
w.set(&d);
cout << w.get() << endl;
}
Przykład 5. Definicja szablonu tablicy.
Przeładowanie operatora [ ] (w10-07-template-tablica.cpp).
#include <iostream>
using namespace std;
template<class T>
class Array {
static const int size = 100;
T A[size];
public:
// przeładowanie operatora [ ]
T& operator[](int index) { return A[index]; }
};
int main() {
Array<int> ia;
// definicja tablicy typu int
Array<double> da; // definicja tablicy typu double
// inicjowanie tablic typu int, double
for(int i = 0; i < 5; i++)
{
ia[i] = i * i;
da[i] = double(i) * 1.414;
}
// przekierowanie na standardowe wyjście wartości elementów tablic
for(int j = 0; j < 5; j++)
cout << j << ": " << ia[j] << ", " << da[j] << endl;
}
6
Programowanie 2. Język C++. Wykład 10.
Przykład 6. Definicja szablonu klasy.
Metoda operuje na atrybucie klasy ( w10-08-template-Dane.cpp)
#include <iostream>
using namespace std;
template <class T> class A
{
public:
A(){}
A(T n);
~A(){}
void pokaz_dane();
protected:
T dane;
};
template <class T> A<T>::A(T x) : dane(x){}
template <class T> void A<T>::pokaz_dane()
{
cout << "dane= " << dane << endl;
}
void main()
{
A<int> a(25);
a.pokaz_dane();
A<char> b('Q');
b.pokaz_dane();
A<double> d(1.25);
d.pokaz_dane();
}
7
Programowanie 2. Język C++. Wykład 10.
Przykład 7. Definicja szablonu klasy z dwoma parametrami.
Metoda operuje na atrybutach klasy (w10-09-template-Dane.cpp).
#include <iostream>
using namespace std;
template <class T1, class T2> class A
{
public:
A(){ cout << "A()" << endl;}
A(T1, T2);
~A(){cout << "~A()" << endl;}
void pokaz_dane();
private:
T1 dane1;
T2 dane2;
};
template <class T1, class T2> A<T1, T2> :: A(T1 x, T2 y) : dane1(x), dane2(y)
{
cout << "A(T1,T2)" << endl;
}
template <class T1, class T2> void A<T1, T2>::pokaz_dane()
{
cout << "dane1= " << dane1 << endl;
cout << "dane2= " << dane2 << endl;
}
void main()
{
A<int, double> a(5,3.5);
a.pokaz_dane();
}
8
Programowanie 2. Język C++. Wykład 10.
Przykład 8. Definicja szablonu klasy.
Przeładowanie operatora << klasy ostream (w10-09-template-str_out.cpp)
#include <iostream>
using namespace std;
class Dane
{
public:
char dane[128];
int i;
double d;
};
ostream& operator << (ostream& str_out, Dane & q)
{
str_out << "q.dane= " << q.dane << endl;
str_out << "q.i
= " << q.i << endl;
str_out << "q.d
= " << q.d << endl;
return str_out;
};
template <class T> class A
{
public:
A(T);
void pokaz_d();
private:
T d;
};
template <class T> A<T>::A(T x): d(x) { }
template <class T> void A<T>::pokaz_d()
{
cout << d << endl; // przeładowany operator <<
}
void main()
{
Dane dane={"tekst", 1000, 21.33};
A<Dane> x(dane);
x.pokaz_d();
}
9
Programowanie 2. Język C++. Wykład 10.
10.4
Szablony jako wstęp do biblioteki STL
Standard Template Library (biblioteka STL, Standardowa Biblioteka Wzorców) zawiera zdefiniowane struktury
danych i algorytmy pozwalające wykonywać operacje na tych strukturach.
Biblioteka STL oparta jest na szablonach.
Komponenty biblioteki STL:
• kontenery (containers), stosowane do zarządzania zbiorami obiektów. Kontenery mogą być
implementowane jako, tablice (arrays), linkowane listy (linked lists), kolejki, mapy.
• iteratory (iterators), stosowane do przeszukiwania kontenerów (zbiorów obiektów), przechodzenia między
obiektami.
• algorytmy, określają operacje wykonywane na zawartości kontenerów lub na obiektach.
Typy kontenerów:
• sequence containers (sekwencyjne kontenery), uporządkowane zbiory, w których kaŜdy element zajmuje
określone połoŜenie. PołoŜenie elementu w kontenerze zaleŜy od czasu i miejsca wstawienia elementu do
kontenera, nie zaleŜy do wartości elementu.
• associative containers (łączone kontenery), zbiór uporządkowanych elementów, w którym połoŜenie
zaleŜy od wartości elementu i algorytmu sortującego.
Przykładami zdefiniowanych w STL sekwencyjnych kontenerów są:
• wektory (vectors),
• kolejki o dwóch końcach, tzn. obiekty moŜna wstawiać na początku lub na końcu kolejki (deques),
• listy (lists),
• tablica stringów.
Przykładami zdefiniowanych w STL łączonych kontenerów są:
• zbiory (sets), multisets, automatyczne sortowanie według określonego algorytmu,
• mapy (maps), multimaps, elementami są pary (klucz, wartość). Automatyczne sortowanie według
określonego algorytmu dla klucza.
Predefiniowane w STL specjalne kontenery (container adapters)
• stos (stack). uporządkowany zbiór elementów, zarządzany według zasady LIFO (last-in-first-out).
• kolejki (queues), uporządkowany zbiór elementów, zarządzany według zasady FIFO (first-in-first-out).
• kolejki z priorytetem (priority queues), uporządkowany zbiór elementów, w którym elementy mogą mieć
określony priorytet w algorytmie sortowania.
Literatura:
•
N. Josuttis, C++ Biblioteka standardowa. Podręcznik programisty, Helion, 2003.
•
SGI, Standard Template Library Programmer's Guide, http://www.sgi.com/tech/stl/
•
A. Stepanov, Notes on Programming, http://www.stepanovpapers.com/notes.pdf
•
D. Musser, G. Derge, A. Saini, C++ Programming with the Standard Template Library, Addison-Wesley, 1998.
10
Programowanie 2. Język C++. Wykład 10.
Przykład 1. UŜycie list (w10-10-template-lista1.cpp).
Metody klasy list uŜyte w programie:
• size()– zwraca liczbę elementów listy.
• begin()-zwraca iterator wskazujący na pierwszy element listy.
• end()-zwraca iterator wskazujący na ostatni element listy.
• pop_front() – usuawa element z początku listy.
• push_front()– dodaje element na początek listy.
// wynik
// działania
// programu
#include <iostream>
#include <list>
using namespace std;
typedef list<int>
typedef list<int>::iterator
IntList;
IntListIterator;
template<class T, class A>
void showList(const list<T, A>& aList)
{
cout << "size() = " << aList.size() << endl;
for (list<T, A>::const_iterator i = aList.begin();
i !=aList.end();
++i
)
cout << *i << endl;
}
void main()
{
IntList
int
size() = 5
0
5
10
15
20
size() = 4
5
10
15
20
size() = 5
100
5
10
15
20
listaA(5);
j = 0;
for (IntListIterator ia = listaA.begin();
ia != listaA.end();
++ia
)
*ia = 5 * j++;
showList(listaA);
// usun pierwszy element
listaA.pop_front();
showList(listaA);
// dodaj nowy element na poczatek listy
listaA.push_front(100);
showList(listaA);
}
11
Programowanie 2. Język C++. Wykład 10.
Przykład 2. UŜycie list (w10-11-template-lista2.cpp).
// wynik
// działania
// programu
#include <iostream>
#include <list>
using namespace std;
typedef list<int>
typedef list<int>::iterator
IntList;
IntListIterator;
template<class T, class A>
void showList(const list<T, A>& aList)
{
cout << "size() = " << aList.size() << endl;
for (list<T,A>::const_iterator i = aList.begin();
i != aList.end();
++i)
cout << *i << endl;
}
void main()
{
IntList
int
listaA(5);
j = 0;
for (IntListIterator ia = listaA.begin();
ia != listaA.end();
++ia)
*ia = 5 * j++;
showList(listaA);
IntList
j = 10;
listaB(6);
for (IntListIterator ib = listaB.begin();
ib != listaB.end();
++ib)
*ib = 2 * j--;
showList(listaB);
IntList listaC = listaA;
IntList listaD = listaB;
// sklej bez sortowania
listaA.merge(listaB);
showList(listaA);
showList(listaB);
// Odwróć kolejnosc elementow w listaA
listaA.reverse();
showList(listaA);
// sortuj i sklej
listaC.sort();
listaD.sort();
listaC.merge(listaD);
showList(listaC);
showList(listaD);
size()
0
5
10
15
20
size()
20
18
16
14
12
10
size()
0
5
10
15
20
20
18
16
14
12
10
size()
size()
10
12
14
16
18
20
20
15
10
5
0
size()
0
5
10
10
12
14
15
16
18
20
20
size()
= 5
= 6
= 11
= 0
= 11
= 11
= 0
}
12
Programowanie 2. Język C++. Wykład 10.
Przykład 3. UŜycie stosu (w10-12-template-stos.cpp).
Metody klasy stack uŜyte w programie:
• size()– zwraca liczbę elementów stosu.
• push()- dodaje element do stosu.
• top() – zwraca referencje (adres)do elementu znajdującego się na szczycie
stosu.
#include <iostream>
#include <stack>
using namespace std;
template<class T, class C>
void ShowStack(stack<T, C>& aStack)
{
cout << "aStack.size()= " << aStack.size() << endl;
if (!aStack.empty())
cout << "aStack.top() = " << aStack.top() << endl;
}
int main()
{
// utwórz stos liczb calkowitych
stack<int> sInt;
ShowStack(sInt);
// wrzuć elementy na stos
for (unsigned int i = 0; i < 5; ++i)
sInt.push(i * 2);
ShowStack(sInt);
sInt.top() = 100;
ShowStack(sInt);
// pobierz wszystkie elementy ze stosu
while (!sInt.empty())
{
cout << sInt.top() << endl;
sInt.pop();
}
return 0;
}
13
Programowanie 2. Język C++. Wykład 10.
Przykład 4. UŜycie zbiorów (w10-13-template-set.cpp).
Metody klasy set uŜyte w programie:
• size()– zwraca liczbę elementów w zbiorze.
• begin()-zwraca iterator wskazujący na pierwszy element w zbiorze.
• end()-zwraca iterator wskazujący na ostatni element w zbiorze.
• insert() – wstawia element, zakres elementów do zbioru.
#include <iostream>
#include <set>
#include <string>
using namespace std;
template <class Kontener>
void pokazZbior( const Kontener & k ) {
Kontener :: const_iterator itr;
for( itr = k.begin( ); itr != k.end( ); itr++ )
cout << *itr << '\n';
}
void main(){
set<string> s; // uporządkowanie alfabetyczne
//set<string, greater<string> > s; // uporządkowanie odwrócone
s.insert( "czerowny" );
s.insert( "zielony" );
s.insert( "niebieski" );
pokazZbior( s );
}
14