Краткие сведения из теории. Овладеть практическими навыками использования шаблонов классов

Лабораторная работа №12.

Шаблоны классов.

Цель работы

Овладеть практическими навыками использования шаблонов классов.

Краткие сведения из теории

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

Механизм шаблонов в C++ допускает применение абстрактного типа в качестве параметра при определении класса или функции.

После того как шаблон класса определен, он может использоваться для определения конкретных классов.

Процесс генерации компилятором определения конкретного класса по шаблону класса и аргументам шаблона называется инстанцированием шаблона (template instantiation).

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

Наиболее широкое применение шаблоны находят при создании контейнерных классов.

Контейнерным называется класс, который предназначен для хранения каким-либо образом организованных данных и работы с ними.

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

Шаблон класса (иначе параметризованный класс) используется для построения родового класса. Создавая родовой класс, вы создаете целое семейство родственных классов, которые можно применять к любому типу данных.

Таким образом, тип данных, которым оперирует класс, указывается в качестве параметра при создании объекта, принадлежащего к этому классу.

Подобно тому, как класс определяет правила построения и формат отдельных объектов, шаблон класса определяет способ построения отдельных классов.

В определении класса, входящего в шаблон, имя класса является не именем отдельного класса, а параметризованным именем семейства классов.

Общая форма объявления параметризованного класса:

Краткие сведения из теории. Овладеть практическими навыками использования шаблонов классов - student2.ru

Краткие сведения из теории. Овладеть практическими навыками использования шаблонов классов - student2.ru

Отметим, что язык позволяет вместо ключевого слова class перед параметром шаблона использовать другое ключевое слово — typename, то есть написать:

template < typename Т>

class point

{ /* ... */ };

После объявления Т используется внутри шаблона точно так же, как имена других типов.

Параметрами шаблонов могут быть абстрактные типы или переменные встроенных типов, таких как int.

В первом случае при инстанцировании на их место подставляются аргументы либо встроенных типов, либо типов, определенных программистом.

Второй вид используется, когда для шаблона предусматривается его настройка некоторой константой. Например, можно создать шаблон для массивов, содержащих n элементов типа Т:

template <class Т, int n>

class Array

{ / * . . . * / };

Тогда, объявив объект:

Array<point, 20> ар;

мы создадим массив из 20 элементов типа point.

Приведем пример использования параметров второго вида:

void f1()

{ cout << "I am f1 () . " << endl; }

void f2()

{ cout << "I am f2 ( ) . " << endl; }

template<void (*pf)()>

struct A

{ void Show()

{ pf();}

};

int main()

{

A<&fl> aa;

aa. Show(); // вывод: I am f1().

A<&f2> ab;

ab. Show();// вывод: I am f2().

return 0;

}

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

Параметры шаблона могут иметь умалчиваемые значения:

template<class T=char, int size=64>

class arr {

T data [size];

int length;

public:

arr():length(size){ }

T& operator [ ] (int i) {

if( i<0 | | i> size){ cout<<”Index error”; exit(1);}

return data[i];

}

};

int main () {

arr<double,5> rf;

arr<int>ri; // массив int , умалчание для size

arr< > rc; // умолчание для обоих параметров

for(int i=0; i<5; i++)

{ rf[i]=i; ri=i*i; rc=’A’+i; }

for(int i=0; i<5; i++)

cout<<rf[i]<< “ “<< ri[i]<< “ “ <<rc[i]<< ‘\t’;

return 0;

}

Наши рекомендации