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

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

Шрифт:

}

В этом фрагменте кода мы сначала проверяем самоприсваивание (например,

v=v
); в этом случае ничего делать не надо. С логической точки зрения эта проверка лишняя, но иногда она позволяет значительно оптимизировать программу. Эта проверка демонстрирует использование указателя
this
, позволяющего проверить, является ли аргумент a тем же объектом, что и объект, из которого вызывается функция-член (т.е.
operator=
). Убедитесь, что этот код действительно работает, если из него удалить инструкцию
this==&a
. Инструкция
a.sz<=space
также включена для оптимизации. Убедитесь, что этот код действительно работает после удаления из него инструкции
a.sz<=space
.

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>

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

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

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

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

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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