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

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

Шрифт:

vector<int> vi;

// ...

printout(vi); // вызов из класса vector

Это простой пример обобщенного программирования, демонстрирующий доступ к данным. Он работает благодаря тому, что как для класса

array
, так и для класса
vector
используется один и тот же интерфейс (функции
size
и операция индексирования). Более подробно этот стиль будет рассмотрен в главах 20 и 21.

19.3.5. Вывод шаблонных аргументов

Создавая объект конкретного класса на основе шаблонного класса, мы указываем шаблонные аргументы. Рассмотрим пример.

array<char,1024> buf; // для массива buf параметр T — char, а N == 1024

array<double,10> b2; // для массива b2 параметр T — double, а N == 10

Для шаблонной функции компилятор обычно выводит шаблонные аргументы из аргументов функций. Рассмотрим пример.

template<class T, int N> void fill(array<T,N>& b, const T& val)

{

for (int i = 0; i<N; ++i) b[i] = val;

}

void f

{

fill(buf, 'x'); // для функции fill параметр T — char,

// а N == 1024,

// потому что аргументом является объект buf

fill(b2,0.0); // для функции fill параметр T — double,

// а N == 10,

// потому что аргументом является объект b2

}

С формальной точки зрения вызов

fill(buf,'x')
является сокращенной формой записи
fill<char,1024>(buf,'x')
, а
fill(b2,0)
— сокращение вызова
fill<double,10>(b2,0)
, но, к счастью, мы не всегда обязаны быть такими конкретными. Компилятор сам извлекает эту информацию за нас.

19.3.6. Обобщение класса vector

Когда мы создавали обобщенный класс

vector
на основе класса “
vector
элементов типа
double
” и вывели шаблон “
vector
элементов типа
T
”, мы не проверяли определения функций
push_back
,
resize
и
reserve
. Теперь мы обязаны это сделать, поскольку в разделах 19.2.2 и 19.2.3 эти функции были определены на основе предположений, которые были справедливы для типа
double
, но не выполняются для всех типов, которые мы хотели бы использовать как тип элементов вектора.

• Как запрограммировать класс

vector<X>
, если тип
X
не имеет значения по умолчанию?

• Как гарантировать, что элементы вектора будут уничтожены в конце работы с ним?

Должны ли мы вообще решать эти проблемы? Мы могли бы заявить: “Не создавайте векторы для типов, не имеющих значений по умолчанию” или “Не используйте векторы для типов, деструкторы которых могут вызвать проблемы”. Для конструкции, предназначенной для общего использования, такие ограничения довольно обременительны и создают впечатление, что разработчик не понял задачи или не думал о пользователях. Довольно часто такие подозрения оказываются правильными, но разработчики стандартной библиотеки к этой категории не относятся. Для того чтобы повторить стандартный класс vector, мы должны устранить две указанные выше проблемы.

Мы можем работать с типами, не имеющими значений по умолчанию, предоставив пользователю возможность задавать это значение самостоятельно.

template<class T> void vector<T>::resize(int newsize, T def = T);

Иначе говоря, используйте в качестве значения по молчанию объект, созданный конструктором

T
, если пользователь не указал иначе. Рассмотрим пример.

vector<double> v1;

v1.resize(100); // добавляем 100 копий объекта double, т.е. 0.0

v1.resize(200, 0.0); // добавляем 200 копий числа 0.0 — упоминание

// излишне

v1.resize(300, 1.0); // добавляем 300 копий числа 1.0

struct No_default {

No_default(int); // единственный конструктор класса No_default

// ...

};

vector<No_default> v2(10); // ошибка: попытка создать 10

  • Читать дальше
  • 1
  • ...
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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