vector<int> v_i;За да дефинираме клас-шаблон, означаваме произволен тип с T и добавяме template<typename T> преди дефиницията на класа. Нека дефинираме наредена двойка елементи с данни от произволен тип:
vector<double> v_d;
vector<Employee> v_e;
template<typename T>Всички член-функции се дефинират също като шаблони.
class Pair {
public:
Pair(T a, T b);
T get_first() const;
T get_second() const;
private:
T first;
T second;
};
Класът List (list2.cpp, list0.cpp) съхранява свързан списък от низове. Използвайки шаблони, List ще може да съхранява стойности от произволен тип, както това става в стандартния клас list от STL. За тази цел дефинираме шаблон на клас, като задаваме формален параметър T на шаблона с конструкцията// pairs.cpp
#include <iostream>
#include <string>
using namespace std;
template<typename T>
class Pair
{
public:
Pair(T a, T b);
T get_first() const;
T get_second() const;
void print() const;
private:
T first;
T second;
};
template<typename T>
Pair<T>::Pair(T a, T b)
{ first = a;
second = b;
}
template<typename T>
T Pair<T>::get_first() const
{ return first;
}
template<typename T>
T Pair<T>::get_second() const
{ return second;
}
template<typename T>
void Pair<T>::print() const
{ cout << "Pair: (" << first << ","
<< second << ")" << endl;
}
int main()
{ Pair<int> integers(10,22);
integers.print();
Pair<double> doubles(1.5, 2.25);
doubles.print();
Pair<string> strings("One", "Two");
strings.print();
char ch; cin >> ch;
return 0;
}
template<typename T> |
class List { |
template<typename T>
class List;
template<typename T>
class Iterator;
template<typename T>
class Link {
public:
Link(T s);
private:
T data;
Link<T> *previous;
Link<T> *next;
friend class List<T>;
friend class Iterator<T>;
};
template<typename T>
class List {
public:
List();
void push_back(T);
void
insert(Iterator<T>, T);
void
erase(Iterator<T>);
Iterator<T>
begin();
Iterator<T> end();
private:
Link<T> *first;
Link<T> *last;
};
template<typename T>
class Iterator {
public:
Iterator();
T operator*() const;
void operator++(int);
void operator--(int);
bool
operator!=(Iterator<T>) const;
private:
Link<T> *position;
Link<T> *last;
friend class List<T>;
};
template<typename T>
Link<T>::Link(T s)
{ data = s;
previous = NULL;
next = NULL; }
template<typename T>
List<T>::List()
{ first = NULL; last = NULL; }
template<typename T>
void List<T>::push_back(T s)
{ Link<T> *newlink = new
Link<T>(s);
if (last == NULL)
{ first = newlink; last =
newlink; }
else
{ newlink->previous = last;
last->next =
newlink;
last = newlink;
}
}
template<typename T>
void
List<T>::insert(Iterator<T> iter, T s)
{ if (iter.position == NULL)
{ push_back(s); return; }
Link<T> *after =
iter.position;
Link<T> *before =
after->previous;
Link<T> *newlink = new
Link<T>(s);
newlink->previous = before;
newlink->next = after;
after->previous = newlink;
if (before == NULL) first =
newlink;
else
before->next = newlink;
}
template<typename T>
void
List<T>::erase(Iterator<T> iter)
{ assert(iter.position != NULL);
Link<T> *remove =
iter.position;
Link<T> *before =
remove->previous;
Link<T> *after =
remove->next;
if (remove == first) first =
after;
else
before->next = after;
if (remove == last) last =
before;
else
after->previous = before;
iter.position = after;
delete remove;
}
template<typename T>
Iterator<T>
List<T>::begin()
{ Iterator<T> iter;
iter.position = first;
iter.last = last;
return iter;
}
template<typename T>
Iterator<T>
List<T>::end()
{ Iterator<T> iter;
iter.position = NULL;
iter.last = last;
return iter;
}
template<typename T>
Iterator<T>::Iterator()
{ position = NULL; last = NULL; }
template<typename T>
T Iterator<T>::operator*()
const
{ assert(position != NULL);
return position->data;
}
template<typename T>
void
Iterator<T>::operator++(int dummy)
{ assert(position != NULL);
position = position->next;
}
template<typename T>
void
Iterator<T>::operator--(int dummy)
{ if (position == NULL)
position = last;
else
position
= position->previous;
assert(position != NULL);
}
template<typename T>
bool
Iterator<T>::operator!=(Iterator<T> b) const
{ return position != b.position; }
int main()
{ List<string> staff;
staff.push_back("Cracker,
Carl");
staff.push_back("Hacker,
Harry");
staff.push_back("Lam, Larry");
staff.push_back("Sandman,
Susan");
/* добавя елемент на четвърто място
*/
Iterator<string> pos;
pos = staff.begin();
pos++; pos++; pos++;
staff.insert(pos, "Reindeer,
Rudolf");
/* отстранява втория елемент */
pos = staff.begin();
pos++;
staff.erase(pos);
/* отпечатва свързания списък */
for (pos = staff.begin(); pos
!= staff.end(); pos++)
cout
<< *pos << "\n";
return 0;
}
Cracker, Carl
Lam, Larry Reindeer, Rudolf Sandman, Susan |
Вложени
класове
В STL класът iterator е дефиниран в класа list:
list<string>::iterator pos = staff.begin();
За да се вложи един клас в друг, вътрешният клас се дефинира във
външния клас:
class List {
...
class Iterator;
...
};
Пример на клaса List със същия интерфейс, както и класа
list от STL.
//list1.cpp
#include <string>
#include <iostream>
#include <cassert>
using namespace std;
template<typename T> class List;
template<typename T>
class Node {
public:
Node(T s);
private:
T data;
Node<T>* previous;
Node<T>* next;
friend class List<T>;
friend class List<T>::Iterator;
};
template<typename T>
class List {
public:
List();
List(const List<T>& b);
~List();
List<T>& operator=(const
List<T>& b);
class Iterator;
void push_back(T s);
void insert(Iterator iter, T s);
Iterator erase(Iterator i);
Iterator begin();
Iterator end();
private:
void copy(const List<T>&
b);
void free();
Node<T>* first;
Node<T>* last;
};
template<typename T>
class List<T>::Iterator {
public:
Iterator();
T operator*() const;
void operator++(int dummy);
void operator--(int dummy);
bool operator==(Iterator b) const;
bool operator!=(Iterator b) const;
private:
Node<T>* position;
Node<T>* last;
friend class List<T>;
};
template<typename T>
List<T>::List()
{ first = NULL;
last = NULL;
}
template<typename T>
List<T>::~List()
{ free();
}
template<typename T>
List<T>::List(const List<T>& b)
{ first = NULL;
last = NULL;
copy(b);
}
template<typename T>
List<T>&
List<T>::operator=(const List<T>& b)
{ if (this != &b)
{ free();
copy(b);
}
return *this;
}
template<typename T>
void List<T>::push_back(T s)
{ Node<T>* newnode = new
Node<T>(s);
if (last == NULL) /* list is empty
*/
{ first = newnode;
last = newnode;
}
else
{ newnode->previous =
last;
last->next =
newnode;
last = newnode;
}
}
template<typename T>
void List<T>::insert(Iterator iter, T s)
{ if (iter.position == NULL)
{ push_back(s);
return;
}
Node<T>* after =
iter.position;
Node<T>* before =
after->previous;
Node<T>* newnode = new
Node<T>(s);
newnode->previous = before;
newnode->next = after;
after->previous = newnode;
if (before == NULL) /* insert at
beginning */
first = newnode;
else
before->next =
newnode;
}
template<typename T>
typename List<T>::Iterator
List<T>::erase(Iterator i)
{ Iterator iter = i;
assert(iter.position != NULL);
Node<T>* remove =
iter.position;
Node<T>* before =
remove->previous;
Node<T>* after =
remove->next;
if (remove == first) first = after;
else
before->next = after;
if (remove == last) last = before;
else
after->previous = before;
iter.position = after;
delete remove;
return iter;
}
template<typename T>
typename List<T>::Iterator
List<T>::begin()
{ Iterator iter;
iter.position = first;
iter.last = last;
return iter;
}
template<typename T>
typename List<T>::Iterator
List<T>::end()
{ Iterator iter;
iter.position = NULL;
iter.last = last;
return iter;
}
template<typename T>
List<T>::Iterator::Iterator()
{ position = NULL;
last = NULL;
}
template<typename T>
T List<T>::Iterator::operator*() const
{ assert(position != NULL);
return position->data;
}
template<typename T>
void List<T>::Iterator::operator++(int
dummy)
{ assert(position != NULL);
position = position->next;
}
template<typename T>
void List<T>::Iterator::operator--(int
dummy)
{ if (position == NULL) position = last;
else
position = position->previous;
assert(position != NULL);
}
template<typename T>
bool
List<T>::Iterator::operator==(Iterator b) const
{ return position == b.position;
}
template<typename T>
bool
List<T>::Iterator::operator!=(Iterator b) const
{ return position != b.position;
}
template<typename T>
Node<T>::Node(T s)
{ data = s;
previous = NULL;
next = NULL;
}
template<typename T>
void List<T>::copy(const
List<T>& b)
{ for (Iterator p = b.begin(); p !=
b.end(); p++)
push_back(*p);
}
template<typename T>
void List<T>::free()
{ while (begin() != end()) erase(begin());
}
int main()
{ List<string> staff;
staff.push_back("Cracker, Carl");
staff.push_back("Hacker, Harry");
staff.push_back("Lam, Larry");
staff.push_back("Sandman, Susan");
/* add a value in fourth place */
List<string>::Iterator pos;
pos = staff.begin();
pos++;
pos++;
pos++;
staff.insert(pos, "Reindeer,
Rudolf");
/* remove the value in second place
*/
pos = staff.begin();
pos++;
staff.erase(pos);
/* print all values */
for (pos = staff.begin(); pos !=
staff.end(); pos++)
cout <<
*pos << "\n";
return 0;
}