Байланысты: Бьерн Страуструп. Язык программирования С . М Бином, 2011
8.7.1 Задание реализации с помощью параметров шаблона В контейнерных классах часто приходится выделять память. Иногда бывает необходимо (или просто
удобно) дать пользователю возможность выбирать из нескольких вариантов выделения памяти, а также
позволить ему задавать свой вариант. Это можно сделать несколькими способами. Один из способов
состоит в том, что определяется шаблон типа для создания нового класса, в интерфейс которого входит
описание соответствующего контейнера и класса, производящего выделение памяти по способу,
описанному в $$6.7.2:
template class Controlled_container
: public Container, private A {
//
...
void
some_function()
{
//
...
T* p = new(A::operator new(sizeof(T))) T;
//
...
}
//
...
};
Шаблон типа здесь необходим, поскольку мы создаем контейнерный класс. Наследование от
Container нужно, чтобы класс Controlled_container можно было использовать как контейнерный
класс. Шаблон типа с параметром A позволит нам использовать различные функции размещения:
class Shared : public Arena { /* ... */ };
class Fast_allocator { /* ... */ };
Controlled_container
ptbl;
Controlled_container tree;
Controlled_container
payroll;
Это универсальный способ предоставлять производным классам содержательную информацию о
реализации. Его положительными качествами являются систематичность и возможность использовать
функции-подстановки. Для этого способа характерны необычно длинные имена. Впрочем, как обычно,
typedef позволяет задать синонимы для слишком длинных имен типов:
typedef
Controlled_container
pp_record;
pp_record payroll;
Обычно шаблон типа для создания такого класса как pp_record используют только в том случае, когда
добавляемая информация по реализации достаточно существенна, чтобы не вносить ее в производный
класс ручным программированием. Примером такого шаблона может быть общий (возможно, для
некоторых библиотек стандартный) шаблонный класс Comparator ($$8.4.2), а также нетривиальные
(возможно, стандартные для некоторых библиотек) классы Allocator (классы для выделения памяти).
Отметим, что построение производных классов в таких примерах идет по "основному проспекту",
который определяет интерфейс с пользователем (в нашем примере это Container). Но есть и "боковые
улицы", задающие детали реализации.