Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

Рассмотрим пример.

// почти реальный вектор элементов типа 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>
).

Иногда шаблонный класс называют порождающим типом (type generator). Процесс генерирования типов (классов) с помощью шаблонного класса по заданным шаблонным аргументам называется специализацией (specialization) или конкретизацией шаблона (template instantiation). Например, классы
vector<char>
и
vector<Poly_line*>
называются специализациями класса
vector
. В простых ситуациях, например при работе с классом
vector
, конкретизация не вызывает затруднений. В более общих и запутанных ситуациях конкретизация шаблона очень сильно усложняется. К счастью для пользователей шаблонов, вся эта сложность обрушивается только на разработчика компилятора.

Конкретизация шаблона (генерирование шаблонных специализаций) осуществляется на этапе компиляции или редактирования связей, а не во время выполнения программы.

Естественно, шаблонный класс может иметь функции-члены. Рассмотрим пример.

void fct(vector<string>& v)

{

int n = v.size;

v.push_back("Norah");

// ...

}

При вызове такой функции-члена шаблонного класса компилятор генерирует соответствующую конкретную функцию. Например, когда компилятор видит вызов

  • Читать дальше
  • 1
  • ...
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: