Добавил:
t.me Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

2 семестр / Примеры. Шаблоны-1

.docx
Скачиваний:
2
Добавлен:
16.07.2023
Размер:
30.5 Кб
Скачать

Код программ привожу не полностью! Тренировок в виде решения предыдущих ЛР было множество, к тому же у каждого свои функции и решения. Поднимайте коды ЛР6 и класса Матрица и вперед!.

Данную ЛР можно делать двумя способами.

  1. Создать простой шаблон функции.

  2. Создать шаблон класса.

Сначала рассмотрим первый вариант на примере следующей задачи: Посчитать количество пар равных чисел, находящихся на одинаковых местах. У нас есть 2 одномерных массива, сравниваем их поэлементно и выдаем ответ.

template <typename T>

int compare1(T* v1, T* v2, int n)

{

int k = 0;

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

if (v1[i] == v2[i])

k++;

return k;

}

Шаблон функции. На вход подаются два вектора одного типа и их размер. На выходе имеем количество, поэтому тут переменная k целого типа. Если бы считали сумму или произведение, то переменная была бы того же типа, что и входной массив.

//главная

int main(void)

{

setlocale(LC_ALL, "Russian");

int i, j, n, k;

cout << "Введите размер массива ";

do { cin >> n; } while (n < 2);

int* v1 = new int[n];

cout << "Первый массив: " << endl;

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

cin >> v1[i];

cout << "Второй массив" << endl;

int* v2 = new int[n];

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

cin >> v2[i];

Отрабатываем сначала на целочисленном типе. Далее заменяем выделенный тип на double, убеждаемся, что шаблон функции работает корректно.

k = compare1(v1, v2, n);

if (k == 0)

cout << "Повторов на одинаковых местах нет";

else

cout << k << " одинаковых чисел на соответствующих местах" << endl;

Вызываем функцию, проверяем, что все работает корректно..

delete[] v1;

delete[] v2;

system("pause");

return 0;

}

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

class complex {

double re, im;

public:

void set_c(double Re = 0, double Im = 0)

{

re = Re; im = Im;

}

double get_c_re() { return re; }

double get_c_im() { return im; }

bool operator== (complex b)

{

return (re == b.re && im == b.im);

}

friend istream& operator>>(istream& in, complex& c);

};

istream& operator>>(istream& in, complex& c)

{

// return (in >> c.re >> c.im); //1. вариант. Без лишних подсказок

//2 вариант (подробнее)

cout << "real = "; in >> c.re;

cout << "image = "; in >> c.im;

return (in);

}

! Рекомендуется сделать в своих работах не только минимум нужных перегрузок операторов, но и другие, например, для вывода информации о комплексном числе.

Теперь рассмотрим более сложный пример – шаблон класса. Для решения моей задачи потребуется класс vect. Я уже приводила пример кода в пояснениях к ЛР 6.

class vect

{

complex* base;

int size;

public:

vect(int n = 1) { size = n; base = new complex[size]; }

~vect() { delete[] base; }

void fill_vect();

void print();

void print_table();

int get_size() { return size; }

int& set_size() { return size; }

complex get_elem(int i) { return base[i]; }

complex& set_elem(int i) {return base[i]; }

complex& elem(int i) { return base[i]; }

int compare(vect& v2);

friend ostream& operator<<(ostream& out, const vect& v);

};

Метод print() можно заменить на перегрузку оператора вывода (дружественная функция внизу класса).

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

Обязательно надо обратить внимание на дружественные функции, там тоже указывается тип.

Пример шаблона класса vect. Новое выделено голубым.

template <class F>

class vect

{

F* base;

int size;

public:

vect(int n = 1) { size = n; base = new F[size]; }

~vect() { delete[] base; }

void fill_vect();

int get_size() { return size; }

int& set_size() { return size; }

F get_elem(int i) { return base[i]; }

F& set_elem(int i) { return base[i]; }

F& elem(int i) { return base[i]; }

int compare(vect<F>& v2);

friend ostream& operator<< <F>(ostream& out, const vect<F>& v);

};

Изменяются только тип значений массива, поэтому везде, где идет обращение к массиву, прописываем тип шаблона (какой буквой укажете – не сильно имеет значение. Главное, чтобы имя удовлетворяло допустимым именам в С++.

template <class T>

ostream& operator<< (ostream& out, const vect<T>& v)

{

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

out << v.base[i] << " ";

return out;

}

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

template <class T>

void vect<T>::fill_vect()

{

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

cin >> base[i];

}

template <class T>

int vect<T>::compare(vect<T>& v2)

{

int k = 0;

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

if (base[i] == v2.base[i])

k++;

return k;

}

int main(void)

{

setlocale(LC_ALL, "Russian");

int i, j, n, k;

cout << "Введите размер массива ";

do { cin >> n; } while (n < 2);

vect<complex> mas(n);

cout << "Первый вектор" << endl;

mas.fill_vect();

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

vect<complex> newmas(n);

cout << "Второй вектор" << endl;

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

cin >> newmas.set_elem(i);

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

cout << endl << "Наши вектора" << endl;

cout << mas << endl;

cout << newmas << endl;

После перегрузки оператора вывода для класса Вектор, наши массивы можно выводить коротко и просто 

k = mas.compare(newmas);

if (k == 0)

cout << "Повторов на одинаковых местах нет";

else

cout << "Одинаковых чисел на соответствующих местах " << k << endl;

system("pause");

return 0;

}

Как и прежде, в k заносим результат работы метода сравнения, далее выводим нужную информацию на экран.

Рекомендуемая литература:

  1. Шаблоны функций https://foxford.ru/wiki/informatika/shablony-funktsiy-v-s (отдельно видео на Ютубе https://youtu.be/HTBkRGXTNoo )

  2. Шаблоны классов https://foxford.ru/wiki/informatika/shablony-klassov-v-s (отдельно видео https://youtu.be/yPGD6zlxmJU )

  3. Соответствующие темы в ранее упомянутых книгах. Например, в пособии Русоновой с. 97 и с. 166.