Бьерн Страуструп - Язык программирования С++. Главы 5-8
Страница 86. Задание реализации с помощью параметров шаблона



8.7.1 Задание реализации с помощью параметров шаблона

 В контейнерных классах часто приходится выделять память. Иногда
 бывает необходимо (или просто удобно) дать пользователю возможность
 выбирать из нескольких вариантов выделения памяти, а также позволить
 ему задавать свой вариант. Это можно сделать несколькими способами.
 Один из способов состоит в том, что определяется шаблон типа для
 создания нового класса, в интерфейс которого входит описание
 соответствующего контейнера и класса, производящего выделение памяти
 по способу, описанному в $$6.7.2:

        template<class T, class A> class Controlled_container
            : public Container<T>, private A {
            // ...
            void some_function()
            {
              // ...
              T* p = new(A::operator new(sizeof(T))) T;
              // ...
            }
            // ...
       };

 Шаблон типа здесь необходим, поскольку мы создаем контейнерный класс.
 Наследование от Container<T> нужно, чтобы класс Controlled_container
 можно было использовать как контейнерный класс. Шаблон типа с
 параметром A позволит нам использовать различные функции размещения:

      class Shared : public Arena { /* ... */ };
      class Fast_allocator { /* ... */ };

      Controlled_container<Process_descriptor,Shared> ptbl;

      Controlled_container<Node,Fast_allocator> tree;

      Controlled_container<Personell_record,Persistent> payroll;

 Это универсальный способ предоставлять производным классам
 содержательную информацию о реализации. Его положительными качествами
 являются систематичность и возможность использовать функции-подстановки.
 Для этого способа характерны необычно длинные имена. Впрочем, как
 обычно, typedef позволяет задать синонимы для слишком длинных имен
 типов:

       typedef
       Controlled_container<Personell_record,Persistent> pp_record;

       pp_record payroll;

 Обычно шаблон типа для создания такого класса как pp_record используют
 только в том случае, когда добавляемая информация по реализации
 достаточно существенна, чтобы не вносить ее в производный класс ручным
 программированием. Примером такого шаблона может быть общий
 (возможно, для некоторых библиотек стандартный) шаблонный класс
 Comparator ($$8.4.2), а также нетривиальные (возможно, стандартные
 для некоторых библиотек) классы Allocator (классы для выделения памяти).
 Отметим, что построение производных классов в таких примерах
 идет по "основному проспекту", который определяет интерфейс с
 пользователем (в нашем примере это Container). Но есть и "боковые
 улицы", задающие детали реализации.

 
« Предыдущая статья   Следующая статья »