Параметры шаблонов

P3.Show(); p4.Show();

Pl.Show(); p2.Show();

point<int> p3(13, 15); // 3

point<short> p4(17, 21); // 4

return 0;

}

Обратите внимание на использование шаблонного класса point главной функцией main():

в строках 1 и 2 шаблон инстанцируется в конкретный класс point с подстановкой вместо Т типа double, в строке 3 — в класс point с подстановкой типа int, в строке 4 — с подстановкой типа short.

Заметим, что наиболее широкое применение шаблоны классов нашли при создании контейнерных классов стандартной библиотеки шаблонов (STL), которые предназначены для работы с такими стандартными структурами, как вектор, список, очередь, множество и т. д. (Еще раз: контейнеры — это объекты, предназначенные для хранения других объектов).

Еще один пример.

// шаблон векторов

template<class T> // Т – параметр шаблона

class Vector // Vector - имя семейства классов

{T* data; // данные класса

int size; // размер пространства

public:

Vector(int); // конструктор

~Vector () { delete [ ]data; } // деструктор

// перегрузка операции “ [ ]”

T& operator [ ] (int i) { return data[i];}

friend ostream & operator << (ostream&, Vector <T>);

};

template<class T> // внешнее определение конструктора шаблона

Vector <T>:: Vector(int n)

{data = new T[n];

size =n;}

// определение перегрузки операции <<

ostream & operator << (ostream& out, Vector <T> X)

{ out<<endl;

for(int i=0;i<X.size; i++)

out<<X[i]<<" "; return out;}

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

Имя параметризованного класса(шаблона)

< фактические параметры шаблона>

имя объекта (параметры конструктора);

т.е. имя конкретного класса будет:

Имя параметризованного класса(шаблона)

< фактические параметры шаблона>

Vector<char> A(5); // вектор А – массив из пяти значений типа

//char, здесь Vector <char> - имя класса

void main()

{clrscr();

// статическте объекты:

Vector<int> X(5);

Vector <char> C(5);

// динамический объект:

Vector<int>*p= new Vector<int> (10);

// заполнение элементов значениями и вывод элементов вектора,

// используя перегруженную операцию []

for(int j =0; j<10; j++)

{(*p)[j]= j; cout<< (*p)[j]<<" ";}

Параметрами шаблонов могут быть абстрактные типы или переменные встроенных типов, таких как 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;

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: