Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
тех прог.doc
Скачиваний:
13
Добавлен:
14.11.2019
Размер:
3.59 Mб
Скачать

Программа 65. Объявление и определение шаблона функции

В данной программе сначала объявляется шаблон функции count0 для подсчета числа нулевых элементов массива, затем дается его определение.

// Файл TmplFunc.cpp

template<class D> // Объявление шаблона функции,

int count0(D *x, int n); // подсчитывающей число нулей в массиве

#include <iostream.h>

int main() // Использование шаблона

{

int x[] = {1, 2, 0, 3, 0, 4, 0, 5, 3, 3, 1, 0, 0}; // Массив из 13 int

double y[] = {0.0, 1.0, 2.0, 0.0, 2.3}; // Массив из 5 double

cout << "Число нулей в x: " << count0(x, 13) << endl;

cout << "Число нулей в y: " << count0(y, 5) << endl;

cin.get();

return 0;

}

// Определение шаблона функции

template<class T>

int count0(T *x, int n) // x – массив элементов

{ // n – число элементов в массиве

int k = 0;

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

if(int(x[i]) == 0)

k++;

return k;

}

Программа выводит:

Число нулей в x: 5

Число нулей в y: 2

21.3.Классы и шаблоны

Шаблон семейства классов определяется инструкцией:

template <СПИСОК_ПАРАМЕТРОВ_ШАБЛОНА>

ОПРЕДЕЛЕНИЕ_КЛАССА

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

Программа 66. Шаблон классов векторов

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

// Файл TmplVect.cpp

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

class Vect{

T *v; // Одномерный массив из элементов типа T

int n; // Размер массива

public:

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

~Vect() // Деструктор

{ delete[] v;}

T& operator[](int i) // Доступ к элементу вектора

{ return v[i]; }

};

При определении функций-членов шаблона классов следует повторить объявление параметра шаблона с помощью template. Определение конструктора имеет вид:

template <class T>

Vect <T>::Vect(int k)

{ n = k; v = new T[n]; }

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

#include <iostream.h>

void main()

{

Vect <int> X(5); // Целочисленный вектор из 5 элементов

Vect<char> S(5); // Символьный вектор

for(int i = 0; i < 5; i++){ // Заполнение векторов

X[i] = i;

S[i] = 'A' + i;

}

for(i = 0; i < 5; i++) // Вывод веторов

cout << " " << X[i] << ' '<< S[i];

cin.get();

}

Приведенная программа выводит:

0 A 1 B 2 C 3 D 4 E

Значением параметра шаблона может быть стандартный тип (int, double,...) или тип, определённый пользователем.

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

Программа 67. Шаблон классов динамических массивов

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

// Файл TmplDArr.cpp

#include <stdlib.h> // Для rand()

#include <time.h>

#include <iostream>

#include<Windows.h> // Для функции CharToOem

char Buff[500]; // Буфер для преобразования русских букв

char* Rus(char* in) // Функция для преобразования русских букв

{

CharToOem(in, Buff); // Функция CharToOem преобразует строку in

return Buff; // в строку Buff, используя кодировку DOS

}

using namespace std;

template <class T, int size = 64> // 64 – значение по умолчанию для size

class DynArr { // Шаблон классов динамических массивов

T* data; // Массив элементов

int n; // Количество элементов

public:

DynArr() // Конструктор

{ data = new T[n = size]; }

~DynArr() // Деструктор

{delete[] data;}

T& operator[](int i) // Доступ к элементу

{ return data[i];}

int SizeArr() // Размер массива

{return n;}

T GetMax(); // Возвращает значение максимального элемента

};

// Определение функции-члена шаблона классов

template <class D, int sz> // Имена параметров шаблона в определении

D DynArr<D, sz>::GetMax() // могут отличатся от их имен в объявлении

{

D max = data[0];

for(int i = 1; i < n; i++)

if(data[i] > max)

max = data[i];

return max;

}

В главной функции создаются два динамических массива: x с размером по умолчанию и y заданного размера. Массивы заполняются случайными числами, генерируемыми функцией int rand(void). Для того, чтобы при каждом запуске программы генерировались различные последовательности чисел, вызывается функция

void srand(unsigned seed);

Ее аргумент задает начальную точку в последовательности псевдослучайных чисел, генерируемых rand. Для получения значения seed использована объявленная в time.h функция

time_t time(time_t *timer);

возвращающая количество секунд, прошедших от полуночи 1 января 1970 г. Это значение записывается также по адресу timer или игнорируется, если timer=NULL. Тип time_t – это новое обозначение для long, введенное с помощью typedef.

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

int main()

{

srand(unsigned(time(NULL))); // Инициализация датчика сл. чисел

DynArr<double> x; // Массив x из 64 double

DynArr<int, 20> y; // Массив y из 20 int

int i;

for(i = 0; i < x.SizeArr(); i++) // Заполнение массива x

x[i] = rand();

cout << Rus("Количество элементов в x: ") << x.SizeArr();

cout << Rus(", максимальное из x: ") << x.GetMax() << endl;

for(i = 0; i < y.SizeArr(); i++) // Заполнение массива y

y[i] = rand();

cout << Rus("Количество элементов в y: ") << y.SizeArr();

cout << Rus(", максимальное из y: ") << y.GetMax();

cin.get();

return 0;

}

При одном из запусков программа напечатала:

Количество элементов в x: 64, максимальное из x: 32635

Количество элементов в y: 20, максимальное из y: 30486