Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_otvety_k_ekzamenu.doc
Скачиваний:
55
Добавлен:
13.04.2015
Размер:
786.94 Кб
Скачать

44. Шаблоны функций и классов. Синтаксис определения шаблонов. Инстанцирование шаблонов. Модель включения и явное инстанцирование.

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

Шаблоны являются еще одной формой повторного использования в языке С++, наряду с композицией объектов и наследованием классов.

Запишем алгоритм вычисления абсолютного значения в виде шаблона функции:

template< typename T >

T abs ( T _value )

{

return ( _value < 0 ) ? - value : value;

}

Ключевое слово template означает, что далее записывается шаблон. В угловых скобках указываются аргументы шаблона - декларация typename T означает, что описание будет производиться относительно неизвестного на данном этапе типа данных T. В дальнейшем это имя может использоваться как в прототипе так и в теле шаблона.

В состав шаблонов функций входит два наборами аргументов:

  • аргументы шаблона (typename T);

  • аргументы функции (T _value).

Аргументы шаблона используются для подстановки конкретных типов, а аргументы функции - в обычных целях, для передачи данных.

Вместо ключевого слова typename можно использовать слово class. С точки зрения поведения в данном контексте эти ключевые слова играют идентичную роль. Ключевое слово typename является предпочтительным из стилистических соображений, поскольку по смыслу вместо аргумента T могут подставляться не только классы, но и встроенные типы, такие как int. Учитывая возможность подстановки встроенных типов, ключевое слово class может сбивать с толку, хотя и не окажет никакого влияния на функциональность.

В качестве фактического заменителя типа T может быть подставлен любой тип данных, если он удовлетворяет ожиданиям шаблона.

Шаблон функции еще не является полноценной функцией, это лишь некоторая промежуточная форма в памяти компилятора. Если шаблон не использовать, никакого машинного кода не будет сгенерировано вообще!

Второй этап компиляции шаблона выполняется при подстановке конкретных типов вместо аргументов. Его называют инстанцированием (instantiation) шаблона. Фактический аргумент для типа T можно указать явно:

std::cout << abs< double >( -2.5 );

std::cout << abs< int >( -2 );

std::cout << abs< Money >( Money( -5, 20 ) ).m_dollars;

либо для простых случаев он будет автоматически выведен (deducted) из контекста по переданным аргументам:

std::cout << abs( -2.5 );

std::cout << abs( -2 );

std::cout << abs( Money( -5, 20 ) ).m_dollars;

Для каждого использования шаблона с уникальным фактическим аргументом компилятор в результате инстанцирования сгенерирует отдельную копию с подставленными вместо T конкретным типом. При этом выполнятся все ранее отложенные компилятором проверки, ожидавшие информации о конкретном типе T.

Если в программе встретится еще один вызов функции-шаблона с точно таким же фактическим аргументом, компилятор будет повторно использовать ранее сгенерированный при первом вызове вариант реализации.

Для явного указания аргументов такого шаблона при вызове следует перечислить фактические типы в угловых скобках через запятую:

short x = 20000;

int result = add< int, char, short >( ‘a’, x);

Автоматический вывод типов может быть получен лишь для передаваемых аргументов:

short x = 20000;

int result = add< int >( ‘a’, x );

Для типа результата аргумент придется указывать в явном виде в любом случае.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]