Шрифт:
Рассмотрим пример.
// почти реальный вектор элементов типа T
template<class T> class vector {
// читается как "для всех типов T" (почти так же, как
// в математике)
int sz; // размер
T* elem; // указатель на элементы
int space; // размер + свободная память
public:
vector:sz(0),elem(0),space(0) { }
explicit vector(int s);
vector(const vector&); // копирующий
конструктор
vector& operator=(const vector&); // копирующее
присваивание
~vector { delete[] elem; } // деструктор
T& operator[](int n) { return elem[n]; } // доступ: возвращает
// ссылку
const T& operator[](int n) const { return elem[n]; }
int size const { return sz; } // текущий размер
int capacity const { return space; }
void resize(int newsize); // увеличивает вектор
void push_back(const T& d);
void reserve(int newalloc);
};
Это определение класса
vector
совпадает с определением класса vector
, содержащего элементы типа double
(см. раздел 19.2.6), за исключением того, что ключевое слово double
теперь заменено шаблонным параметром T
. Этот шаблонный класс vector
можно использовать следующим образом:
vector<double> vd; // T — double
vector<int> vi; // T — int
vector<double*> vpd; // T — double*
vector< vector<int> > vvi; // T — vector<int>, в котором T — int
vector<char>
, он генерирует примерно такой код:
class vector_char {
int sz; // размер
char* elem; // указатель на элементы
int space; // размер + свободная память
public:
vector_char;
explicit vector_char(int s);
vector_char(const vector_char&); // копирующий конструктор
vector_char& operator=(const vector_char &); // копирующее
// присваивание
~vector_char ; // деструктор
char& operator[] (int n); // доступ: возвращает ссылку
const char& operator[] (int n) const;
int size const; // текущий размер
int capacity const;
void resize(int newsize); // увеличение
void push_back(const char& d);
void reserve(int newalloc);
};
Для класса
vector<double>
компилятор генерирует аналог класса vector
, содержащий элементы типа double
(см. раздел 19.2.6), используя соответствующее внутреннее имя, подходящее по смыслу конструкции vector<double>
).
vector<char>
и vector<Poly_line*>
называются специализациями класса vector
. В простых ситуациях, например при работе с классом vector
, конкретизация не вызывает затруднений. В более общих и запутанных ситуациях конкретизация шаблона очень сильно усложняется. К счастью для пользователей шаблонов, вся эта сложность обрушивается только на разработчика компилятора. Конкретизация шаблона (генерирование шаблонных специализаций) осуществляется на этапе компиляции или редактирования связей, а не во время выполнения программы.
Естественно, шаблонный класс может иметь функции-члены. Рассмотрим пример.
void fct(vector<string>& v)
{
int n = v.size;
v.push_back("Norah");
// ...
}
При вызове такой функции-члена шаблонного класса компилятор генерирует соответствующую конкретную функцию. Например, когда компилятор видит вызов