Литмир - Электронная Библиотека
A
A

19.2.6. Предыдущая версия класса vector

Итак, мы получили почти реальный класс

vector
для чисел типа
double
.

// почти реальный вектор чисел типа double

class vector {

/*

 инвариант:

 для 0<=n<sz значение elem[n] является n- м элементом

 sz<=space;

 если sz<space, то после elem[sz–1] есть место

 для (space–sz) чисел типа double

*/

  int sz;       // размер

  double* elem; // указатель на элементы (или 0)

  int space;    // количество элементов плюс количество слотов

public:

  vector():sz(0),elem(0),space(0) { }

  explicit vector(int s):sz(s),elem(new double[s]),space(s)

  {

    for (int i=0; i<sz; ++i) elem[i]=0; // элементы

                                        // инициализированы

  }

  vector(const vector&);             // копирующий конструктор

  vector& operator=(const vector&);  // копирующее присваивание

  ~vector() { delete[] elem; }       // деструктор

  double& operator[ ](int n) { return elem[n]; }  // доступ

  const double& operator[](int n) const { return elem[n]; }

  int size() const { return sz; }

  int capacity() const { return space; }

  void resize(int newsize);           // увеличение

  void push_back(double d);

  void reserve(int newalloc);

};

Обратите внимание на то, что этот класс содержит все основные операции (см. раздел 18.3): конструктор, конструктор по умолчанию, копирующий конструктор, деструктор. Он также содержит операции для доступа к данным (индексирование

[]
), получения информации об этих данных (
size()
и
capacity()
), а также для управления ростом вектора (
resize()
,
push_back()
и
reserve()
).

19.3. Шаблоны

Однако нам мало иметь вектор, состоящий из чисел типа

double
; мы хотим свободно задавать тип элементов наших векторов. Рассмотрим пример.

vector<double>

vector<int>

vector<Month>

vector<Window*>          // вектор указателей на объекты класса Window

vector< vector<Record> > // вектор векторов из объектов класса Record

vector<char>

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Для этого мы должны научиться определять шаблоны. На самом деле мы с самого начала уже использовали шаблоны, но до сих пор нам не приходилось определять их самостоятельно. Стандартная библиотека содержит все необходимое, но мы не должны полагаться на готовые рецепты, поэтому следует разобраться, как спроектирована и реализована стандартная библиотека, например класс
vector
и функция
sort()
(разделы 21.1 и Б.5.4). Это не просто теоретический интерес, поскольку, как обычно, средства и методы, использованные при создании стандартной библиотеки, могут помочь при работе над собственными программами. Например, в главах 21-22 мы покажем, как с помощью шаблонов реализовать стандартные контейнеры и алгоритмы, а в главе 24 продемонстрируем, как разработать класс матриц для научных вычислений.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 По существу, шаблон (template) — это механизм, позволяющий программисту использовать типы как параметры класса или функции. Получив эти аргументы, компилятор генерирует конкретный класс или функцию. 

19.3.1. Типы как шаблонные параметры

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Итак, мы хотим, чтобы тип элементов был параметром класса
vector
. Возьмем класс
vector
и заменим ключевое слово
double
буквой
T
, где
T
— параметр, который может принимать значения, такие как
double
,
int
,
string
, vector<Record> и Window*. В языке С++ для описания параметра
T
, задающего тип, используется префикс
template&lt;class T&gt;
, означающий “для всех типов
T
”.

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

// почти реальный вектор элементов типа T

template&lt;class T&gt; class vector {

  // читается как &quot;для всех типов T&quot; (почти так же, как

  // в математике)

  int sz;      // размер

  T* elem;     // указатель на элементы

  int space;   // размер + свободная память

public:

  vector():sz(0),elem(0),space(0) { }

  explicit vector(int s);

  vector(const vector&amp;);            // копирующий
 конструктор

  vector&amp; operator=(const vector&amp;); // копирующее
 присваивание

256
{"b":"847443","o":1}