Kontakt  |  PRS 170  |  ALK 420  |  PZR 420  |  SIK 420  |  JPR 222  |  SOP 121


Języki programowania - ćwiczenia 6


Temat zajęć: Język C++: szablony i klasy STL.

 Szablony funkcji i klas

Szablony funkcji i klas są to odpowiednie fragmenty kodu parametryzowane typem danych. W momencie implementacji szablonu co najmniej jeden typ danych, na których operuje funkcja czy które zawiera klasa, jest nieznany. Szablony są konkretyzowane w momencie ich użycia - wówczas należy jawnie podać typ danych, dla którego ma zostać utworzona funkcja czy klasa wg określonego wcześniej szablonu.


 Przykład 1

Składnia definicji i wykorzystania szablonów funkcji. Definiujemy dwa szablony: funkcji wypisującej zawartość tablicy i funkcji sortującej tablicę.

Solution Visual Studio  pobierz  

Plik c7p1.cpp  pobierz  
#include <iostream>

using namespace std;

// definicja szablonu funkcji
template<class T>
void sortuj(T *tab, int rozm)
{
T tmp;
for (int i=0; i<rozm; i++)
for (int j=0; j<rozm-1; j++)
if (tab[j]>tab[j+1]) {
tmp = tab[j];
tab[j] = tab[j+1];
tab[j+1] = tmp;
}
}

// definicja szablonu funkcji
// w definicji szablonu typename T i class T sa tozsame
template<typename T>
void wypisz(T *tab, int rozm)
{
for (int i=0; i<rozm; i++)
cout << tab[i] << " , ";
cout << endl;
}

int main()
{
int i;
int t1[4];
double t2[5];
for (i=0; i<4; i++) {
t1[i] = 5-i;
t2[i] = 6-i;
}
t2[4] = 1;

// kompilator generuje wypisz dla T = int
wypisz<int>(t1, 4);

// kompulator generuje wypisz dla T = double
wypisz<double>(t2, 5);

// kompilator generuje sortuj dla T = int
sortuj<int>(t1, 4);

// kompilator generuje sortuj dla T = double
sortuj<double>(t2, 5);

wypisz<int>(t1, 4);
wypisz<double>(t2, 5);

return 0;
}

 Przykład 2

Szablon klasy reprezentującej tablicę. Przeciążony operator indeksowania, przypisania i zapisania w strumieniu.

Solution Visual Studio  pobierz  

Plik c7p2.h  pobierz  
#pragma once

#include <iostream>

using namespace std;

template<class T>
class Array {

private:
T *buf;
int len;

public:
Array(int size);
Array(const Array<T> &a);
~Array();

T& operator[](int index) const;
int length() const;
void operator=(const Array<T> &a);
};

template<class T>
ostream& operator<<(ostream &o, const Array<T> &a);

Plik c7p2.cpp  pobierz  
#include "c7p2.h"

template<class T>
Array<T>::Array(int size)
{
buf = new T[size];
len = size;
}

template<class T>
Array<T>::Array(const Array<T> &a)
{
buf = new T[a.length()];
len = a.length();
for (int i=0; i<len; i++) {
buf[i] = a[i];
}
}

template<class T>
Array<T>::~Array()
{
delete[] buf;
}

template<class T>
T& Array<T>::operator[](int index) const
{
if (index < len) return buf[index];
else return buf[len];
}

template<class T>
int Array<T>::length() const
{
return len;
}

template<class T>
void Array<T>::operator=(const Array<T> &a)
{
delete[] buf;
buf = new T[a.length()];
len = a.length();
for (int i=0; i<len; i++) {
buf[i] = a[i];
}
}

template<class T>
ostream& operator<<(ostream &o, const Array<T> &a)
{
for (int i=0; i<a.length(); i++) {
o << a[i];
if (i < a.length()-1)
o << " , ";
}
return o;
}

// ----------------------------------------------------------------

int main()
{
Array<int> a(4);
Array<double> *b = new Array<double>(3);

a[0] = 1; a[1] = 2; a[2] = 3; a[3] = 4;
(*b)[0] = 1.0; (*b)[1] = 2.0; (*b)[2] = 3.0;

cout << a << endl;
cout << *b << endl;

delete b;

return 0;
}

 Zadanie 1

Zaimplementować szablon funkcji, która odwróci kolejność elementów w podanym obiekcie klasy Array z przykładu 2. Przetestować funkcję na tablicach zawierających liczby całkowite i łańcuchy tekstowe.
Zmodyfikować klasę Array tak, aby możliwa była zmiana rozmiaru tablicy (dodać metodę Resize(int newsize)), przy czym zmiana rozmiaru ma zachowywać elementy w tablicy od elementu 0 do min{len, newsize}. Zmodyfikować funkcję main z przykładu 2 tak, aby sprawdzić poprawność zaimplementowanej zmiany rozmiaru tablicy.

 Zadanie 2

Zaimplementować szablony klas reprezentujące listę podwójnie wiązaną. W programie powinien znaleźć się szablon klasy ListItem (pojedynczy element listy zawierający pole danych oraz wskaźniki na element poprzedni i następny) oraz szablon klasy List, zawierający wskaźniki na głowę i ogon listy, aktualny rozmiar listy oraz metody służące do dołączania elementów na początku i na końcu listy oraz wyjmowania elementów z początku i końca listy. Próba wyjęcia elementu z pustej listy powinna zwracać jako dane domyślny element klasy parametryzujące T, czyli T(). Dodatkowo proszę zaimplementować metody wstawiające element przed i za elementem o podanym numerze oraz operator indeksowania aby możliwy był dostęp do elementu listy o podanym indeksie.

 Zadanie 3

Zakładając, że lista z zadania 2 została zaimplementowana, proszę zaimplementować szablon funkcji sortującej elementy listy. Funkcja jako parametr powinna przyjmować obiekt klasy List i zwracać nowy obiekt klasy List, zawierający posortowaną listę.

 Zadanie 4

Zaimplementować przeciążony operator zapisu listy do strumienia wyjściowego.
Przetestować klasy z zadań 2 i 3 oraz zaimplementowany operator zapisu do strumienia na listach zawierających dane liczbowe (całkowite i rzeczywiste).

 Zadanie 5

Przeciążyć operator dodawania dla obiektów klasy Array z przykładu 2. Dla tablic t1 i t2 operator powinien zwracać tablicę powstałą przez dołączenie tablicy t2 na koniec tablicy t1. Same tablice t1 i t2 (operandy) powinny pozostać nietknięte.


 Standard Template Library

Na bazie szablonów została zaimplementowana biblioteka STL (Standard Template Library), która obecnie wchodzi w skład standardowej biblioteki C++. Dokumentację STL można znaleźć np. w plikach pomocy Borland C++ czy MS Visual C++ lub na stronach WWW, na przykład:


Valid HTML 4.01!