C++. Приклади реалізації шаблонних функцій та перевантажених шаблонних функцій. Обробка одиночних елементів. Обробка масивів

Приклади реалізації шаблонних функцій та перевантажених шаблонних функцій. Обробка одиночних елементів. Обробка масивів

У даній темі продемонстровано застосування механізму шаблонів C++ для реалізації первантажених шаблонних функцій. Наведено рішення декількох відомих задач. За даними прикладами можна навчитись розробляти власні шаблонні функції які обробляють як одинарні елементи, так і масиви елементів.


Зміст


1. Приклади реалізацій шаблонних функцій

1.1. Приклад шаблонної функції пошуку максимуму між двома елементами

У прикладі реалізовано шаблон функції Max() (шаблонну функцію) для узагальненого типу T, яка визначає максимальне значення між двома параметрами a, b.

#include <iostream>
using namespace std;

// Тема. Шаблони функції

// Шаблон функції пошуку максимального значення між 2 значеннями
template <class T>
T Max(T a, T b)
{
  if (a > b) return a;
    return b;
}

void main()
{
  // Демонстрація шаблонної функції Max()
  // 1. Для типів int
  int i1, i2, maxInt;

  // 1.1. Ввід цілих чисел i1, i2
  cout << "Enter integers:" << ::endl;
  cout << "i1 = ";
  cin >> i1;
  cout << "i2 = ";
  cin >> i2;

  // 1.2. Виклик шаблонної функції Max(T, T) => Max(int, int)
  maxInt = Max(i1, i2);

  // 1.3. Вивід результату
  cout << "maxInt = " << maxInt << endl;

  // 2. Для типів float
  float f1, f2, maxFloat;

  // 2.1. Ввід чисел f1, f2
  cout << "Enter floats:" << ::endl;
  cout << "f1 = ";
  cin >> f1;
  cout << "f2 = ";
  cin >> f2;

  // 2.2. Виклик шаблонної функції Max(T, T) => Max(float, float)
  maxFloat = Max(f1, f2);

  // 2.3. Вивід результату
  cout << "maxFloat = " << maxFloat << endl;

  // 3. Для типів char
  char c1, c2, maxChar;

  // 3.1. Ввід значень c1, c2
  cout << "Enter chars:";
  cout << "\nc1 = ";
  cin >> c1;
  cout << "c2 = ";
  cin >> c2;

  // 3.2. Виклик шаблонної функції Max(T, T) => Max(char, char)
  maxChar = Max(c1, c2);

  // 3.3. Вивід результату
  cout << "maxChar = " << maxChar << endl;
  system("pause");
}

Результат роботи програми:

Enter integers:
i1 = 2
i2 = 7
maxInt = 7
Enter floats:
f1 = 2.56
f2 = 3.55
maxFloat = 3.55
Enter chars:
c1 = f
c2 = q
maxChar = q

 

1.2. Приклад шаблонної функцїі обчислення середнього арифметичного значень елементів масиву

У прикладі розроблено шаблонну функцїю Average() для пошуку середнього арифметичного значень двовимірного масиву.

Оскільки функція Average() обчислює середнє арифметичне на основі значень елементів масиву, то цей масив повинен передаватись у функцію. Також у функцію передається розмір масиву.

Текст застосунку, створеного за шаблоном Console Application наведено нижче.

#include <iostream>
using namespace std;

// Тема. Шаблони функції
// Використовується ключове слово typename або class.
// Функція отримує 2 параметри:
// - count - к-сть елементів у масиві Array[];
// - Array[] - масив елементів типу T.
template <typename T>
double Average(int count, T Array[])
{
  // 1. Оголосити змінну avg типу double,
  //   оскільки середнє арифметичне буде дійсним числом
  double avg;

  // 2. Занулити значення змінної avg перед просумовуванням
  avg = 0.0;

  // 3. Обчислити суму елементів масиву Array[]
  for (int i = 0; i < count; i++)
    avg += Array[i];

  // 4. Обчислити середнє арифметичне
  avg /= count;

  // 5. Повернути значення avg
  return avg;
}

void main()
{
  // Демонстрація шаблонної функції Average(int, T[])
  // 1. Для типів int
  // 1.1. Оголосити змінні
  int countInt = 5; // к-сть елементів у масиві AI
  int AI[] = { 2, 4, -1, 70, 18 }; // ініціалізація масиву AI
  double avg; // середнє арифметричне - результат

  // 1.2. Виклик шаблонної функції Average(int, T[]) => Average(int, int[])
  avg = Average(countInt, AI);

  // 1.3. Виведення результату на екран
  cout << "Average for AI = " << avg << endl;

  // 2. Для типів float
  // 2.1. Оголосити змінні
  int countFloat = 6;
  float AF[] = { 2.8f, 3.2f, -1.4f, 0.5f , 1.2f, 10.2f };

  // 2.2. Виклик шаблонної функції Average(int, T[]) => Average(int, float[])
  avg = Average(countFloat, AF);

  // 2.3. Виведення результату на екран
  cout << "Average for AF = " << avg << endl;

  system("pause");
}

Результат роботи програми

Average for AI = 18.6
Average for AF = 2.75

 

1.3. Приклад реалізації шаблонних функцій копіювання масиву та виведення масиву на екран

Завдання. Написати шаблон функції CopyArray(), яка копіює елементи одновимірного масиву A[] в масив B[]. Розміри масивів вважати однаковими. Виведення масиву результату реалізувати в шаблонній функції Print().

Текст програмного рішення наступний.

#include <iostream>
using namespace std;

// Шаблон функції CopyArray().
// Функція копіює один масив в інший: A[]=>B[]
// Параметри:
// - count - кількість елементів у масивах;
// - A[] - масив-джерело, елементи масиву мають тип Type;
// - B[] - масив-призначення, елементи масиву мають тип Type.
template <class Type>
void CopyArray(int count, Type A[], Type B[])
{
  for (int i = 0; i < count; i++)
  {
    B[i] = A[i];
  }
}

// Шаблон функції Print().
// Функція виводить масив узагальненого типу TT на екран
// Параметри:
// - count - кількість елементів у масиві;
// - Array[] - масив елементів типу TT, який потрібно вивести.
template <class TT>
void Print(int count, TT Array[])
{
  cout << "Items of array:" << ::endl;
  for (int i = 0; i < count; i++)
  {
    cout << Array[i] << "\t";
  }
  cout << endl;
}

void main()
{
  // Демонстрація шаблонної функції CopyArray()
  // 1. Оголосити спільну константу
  const int MAX_ITEMS = 10;

  // 2. Демонстрація для типу int
  // 2.1. Оголосити два масиви типу int
  int AI[] = { 1, -3, 2, 4, 5 }; // масив-джерело
  int BI[MAX_ITEMS]; // масив-призначення

  // 2.2. Виклик шаблонної функції CopyArray()
  CopyArray(5, AI, BI);

  // 2.3. Виклик шаблонної функції Print()
  cout << "Array BI[]. ";
  Print(5, BI);

  // 3. Демонстрація для типу float
  // 3.1. Оголосити два масиви типу float
  float AF[] = { -2.4, 3.8, -1.5, 7.75 };
  float BF[MAX_ITEMS];

  // 3.2. Виклик шаблонної функції CopyArray()
  CopyArray(4, AF, BF);

  // 3.3. Виклик шаблонної функції Print()
  cout << "Array BF[]. ";
  Print(4, BF);
}

Результат роботи програми

Array BI[]. Items of array:
1       -3     2       4       5
Array BF[]. Items of array:
-2.4   3.8     -1.5     7.75

 



2. Приклади реалізацій перевантажених шаблонних функцій

2.1. Приклад перевантаження шаблонної функції пошуку максимуму між 2, 3, 4 параметрами

У прикладі реалізовано перевантаження шаблонної функції Max(), яка знаходить максимальне значення між отримуваними параметрами. Функція реалізована для двох, трьох та 4 параметрів.

Текст демонстраційної програми наступний:

#include <iostream>
using namespace std;

// Тема. Перевантаження шаблонів функцій
// Перевантаження шаблонної функції з іменем Max().

// 1. Шаблон функції Max(T, T),
//   яка визначає максимум між 2 параметрами
template <class T>
T Max(T a, T b)
{
  if (a > b) return a;
    return b;
}

// 2. Шаблон функції Max(T, T, T),
//   яка визначає максимум між 3 параметрами
template <class T>
T Max(T a, T b, T c)
{
  T maximum = a;
  if (maximum < b)
    maximum = b;
  if (maximum < c)
    maximum = c;
  return maximum;
}

// 3. Шаблон функції Max(T, T, T),
//   яка визначає максимум між 4 параметрами
template <class T>
T Max(T a, T b, T c, T d)
{
  T maximum = a;
  if (maximum < b) maximum = b;
  if (maximum < c) maximum = c;
  if (maximum < d) maximum = d;
  return maximum;
}

void main()
{
  // Демонстрація перевантаженої шаблонної функції Max()
  // 1. Для двох параметрів
  int i1, i2, maxInt_2;

  // 1.1. Ввід цілих чисел i1, i2
  cout << "Enter integers:" << ::endl;
  cout << "i1 = ";
  cin >> i1;
  cout << "i2 = ";
  cin >> i2;

  // 1.2. Виклик шаблонної функції Max(T, T) => Max(int, int)
  maxInt_2 = Max(i1, i2);

  // 1.3. Вивід результату
  cout << "maxInt = " << maxInt_2 << endl;

  // 2. Для 3-х параметрів типу float
  float f1, f2, f3, maxFloat_3;

  // 2.1. Ввід чисел f1, f2, f3
  cout << "Enter floats:" << ::endl;
  cout << "f1 = ";
  cin >> f1;
  cout << "f2 = ";
  cin >> f2;
  cout << "f3 = ";
  cin >> f3;

  // 2.2. Виклик шаблонної функції Max(T, T, T) => Max(float, float, float)
  maxFloat_3 = Max(f1, f2, f3);

  // 2.3. Вивід результату
  cout << "maxFloat = " << maxFloat_3 << endl;

  // 3. Для 4-х параметрів типу double
  double d1, d2, d3, d4, maxDouble;

  // 3.1. Ввід значень d1, d2, d3, d4
  cout << "Enter doubles:";
  cout << "\nd1 = ";
  cin >> d1;
  cout << "d2 = ";
  cin >> d2;
  cout << "d3 = ";
  cin >> d3;
  cout << "d4 = ";
  cin >> d4;

  // 3.2. Виклик шаблонної функції Max(T, T, T, T)
  //     Max(T, T, T, T) => Max(double, double, double, double)
  maxDouble = Max(d1, d2, d3, d4);

  // 3.3. Вивід результату
  cout << "maxDouble = " << maxDouble << endl;
  system("pause");
}

Результат роботи програми:

Enter integers:
i1 = 2
i2 = 5
maxInt = 5
Enter floats:
f1 = 2.56
f2 = 3.8
f3 = 4.44
maxFloat = 4.44
Enter doubles:
d1 = 2.96
d2 = 1.35
d3 = 2.88
d4 = 3.54
maxDouble = 3.54

 

2.2. Приклад перевантаження шаблонної функції, яка визначає кількість додатних елементів для масивів різних розмірностей

 

#include <iostream>
using namespace std;

// Перевантаження шаблону функції (шаблонної функції).

// Оголосити глобальні константи меж статичного масиву
const int MAX_ITEMS_1 = 10;
const int MAX_ITEMS_2 = 10;
const int MAX_ITEMS_3 = 10;

// Функція CountItems() визначає кількість додатніх елементів.
// 1. Реалізація для одновимірного масиву
template <typename T>
int CountItems(int n, T Array[])
{
  int count = 0; // результат

  // цикл обчислення count
  for (int i = 0; i < n; i++)
    if (Array[i] > 0)
      count++;

  // повернути результат
  return count;
}

// 2. Реалізація для двовимірного масиву
// Параметри:
// - m, n - розміри масиву
// - Array - двовимірний масив
template <class Type>
int CountItems(int m, int n, Type Array[][MAX_ITEMS_2])
{
  int count = 0; // результат

  // вкладені цикли обчислення k
  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      if (Array[i][j] > 0)
        count++;

  // повернення результату
  return count;
}

// 3. Реалізація для тривимірного масиву
// Параметри:
// - m, n - розміри масиву
// - Array - тривимірний масив
template <class T>
int CountItems(int m, int n, int d, T Array[][MAX_ITEMS_2][MAX_ITEMS_3])
{
  int count = 0; // результат

  // цикл обчислення count
  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      for (int k = 0; k < d; k++)
        if (Array[i][j][k] > 0)
          count++;

  // повернути результат
  return count;
}

void main()
{
  // Демонстрація перевантаженої шаблонної функції CountItems()
  // 1. Для одновимірного масиву типу double
  // 1.1. Оголосити внутрішні змінні
  double AD[MAX_ITEMS_1] = { 2.5, -1.1, 3.5, 8.2 }; // ініціалізація масиву

  int count1;

  // 1.2. Викликати функцію CountItems(int, double[])
  count1 = CountItems(4, AD); // count1 = 3

  // 1.3. Вивести результат
  cout << "count1 = " << count1 << endl;

  // 2. Для двовимірного масиву типу short
  // 2.1. Оголосити внутрішні змінні
  short AS[MAX_ITEMS_1][MAX_ITEMS_2] =
  {
    { 3, 5, 2},
    { 4, 2,-5},
    {-1,-2,-3},
    { 5,-8,-4}
  };
  int count2;

  // 2.2. Викликати функцію CountItems(int, int, short[][])
  count2 = CountItems(4, 3, AS);

  // 2.3. Вивести результат
  cout << "count2 = " << count2 << endl;

  // 3. Для тривимірного масиву типу float. Розмір масиву 2*3*4
  // 3.1. Оголосити внутрішні змінні
  float AF[MAX_ITEMS_1][MAX_ITEMS_2][MAX_ITEMS_3]
  {
    {
      {   1.2f, -2.3f, -4.4f, 2.5f },
      {   4.2f, -3.3f, -1.8f, -0.1f },
      { -1.8f, -2.5f, 3.3f, 4.2f }
    },
    {
      {   4.8f, -1.2f, 3.5f, 8.8f },
      {   1.1f, 0.5f, 0.8f,   2.5f },
      {   4.6f, 1.3f, -2.2f, 1.8f }
    }
  };
  int count3;

  // 3.2. Викликати функцію CountItems(int, int, int, float[][][])
  count3 = CountItems(2, 3, 4, AF);

  // 3.3. Вивести результат
  cout << "count3 = " << count3 << endl;
}

Результат роботи програми

count1 = 3
count2 = 6
count3 = 15

 

2.3. Приклад перевантаження шаблонної функції, яка формує динамічні масиви різних розмірностей

Завдання. Написати перевантажену шаблонну функцію FormArray(), яка заповнює одновимірний та двовимірний динамічні масиви випадковими елементами. Виведення елементів масивів реалізувати з допомогою перевантаженої шаблонної функції PrintArray(), яка також має дві реалізації: для одновимірних та двовимірних масивів.

Текст програми, створеної за шаблоном Console Application наступний:

#include <iostream>
#include <time.h>
using namespace std;

// Перевантаження шаблонної функції FormArray()

// 1. Формування одновимірного масиву
// Параметри:
// - count - кількість елементів у масиві;
// - Array[] - масив елементів типу T.
template <class T>
void FormArray(int count, T* Array)
{
  // 1. Ініціалізувати генератор випадкових чисел
  srand(time(NULL));

  // 2. Записати в масив випадкові числа від 0 до 100
  for (int i = 0; i < count; i++)
    Array[i] = (T)(rand() % 101);
}

// 2. Формування двовимірного масиву
// Параметри:
// - m, n - розміри масиву;
// - Array - двовимірний масив елементів типу T
template <class T>
void FormArray(int m, int n, T** Array)
{
  // 1. Ініціалізувати дані
  srand(time(NULL));

  // 2. Заповнити масив випадковими значеннями
  for (int i = 0; i < m; i++)
    for (int j = 0; j < n; j++)
      Array[i][j] = (T)(rand() % 101);
}

// Перевантажена шаблонна функція виведення масиву на екран
// 1. Реалізація для одновимірного масиву
template <class T>
void PrintArray(int count, T* A)
{
  cout << "Items of one-dimensional array: " << endl;
  for (int i = 0; i < count; i++)
    cout << A[i] << "\t";
  cout << endl;
}

// 2. Реалізація для двовимірного масиву типу T
// Параметри:
// - m, n - розмірність масиву;
// - A - двовимірний масив, елементи якого мають тип T
template <class T>
void PrintArray(int m, int n, T** A)
{
  cout << "Items of two-dimensional array: " << endl;
  for (int i = 0; i < m; i++)
  {
    for (int j = 0; j < n; j++)
      cout << A[i][j] << "\t";
    cout << endl;
  }
}

void main()
{
  // Демонстрація перевантаження шаблонних функцій

  // 1. Одновимірний масив типу int
  // 1.1. Оголосити динамічний масив цілих чисел та його розмірність
  int* AI = nullptr;
  int count1;

  // 1.2. Ввести розмір масиву
  cout << "count = ";
  cin >> count1;

  try
  {
    // 1.3. Спроба виділити пам'ять для масиву
    AI = new int[count1];
  }
  catch (bad_alloc ba)
  {
    // Якщо пам'ять не виділено, то вийти з програми
    // ba.what() - текст системної помилки виділення пам'яті
    cout << "Error. " << ba.what() << endl;
    return;
  }

  // 1.4. Якщо пам'ять виділено добре,
  //       то викликати шаблонну функцію формування елементів масиву
  FormArray(count1, AI);

  // 1.5. Роздрукувати масив на екрані
  PrintArray(count1, AI);

  // 1.6. Після закінчення роботи звільнити пам'ять для масиву AI
  if (AI!=nullptr) delete[] AI;

  // 2. Демонстрація виклику FormArray() та PrintArray()
  //   для двовимірного масиву типу double
  // 2.1. Оголосити змінні
  double** AD = nullptr; // двовимірний масив
  int m, n; // розмірність масиву

  // 2.2. Ввести розмір масиву
  cout << "Enter the size of array: " << endl;
  cout << "m = ";
  cin >> m;
  cout << "n = ";
  cin >> n;

  // 2.3. Виділити пам'ять для масиву AD
  try
  {
    // Спроба виділення пам'яті
    // для масиву покажчиків на тип double
    AD = (double**) new double*[m];

    // для кожного елементу масиву
    for (int i = 0; i < m; i++)
      AD[i] = new double[n];
  }
  catch (bad_alloc ba)
  {
    cout << "Error. " << ba.what() << endl;
    return;
  }

  // 2.4. Викликати функцію FormArray(int, int, T**) => FormArray(int, int, double**)
  FormArray(m, n, AD);

  // 2.5. Викликати функцію PrintArray(int, int, T**) => PrintArray(int, int, double**)
  PrintArray(m, n, AD);

  // 2.6. Звільнити пам'ять, раніше виділену для масиву AD
  if (AD != nullptr)
    delete[] AD;
}

Результат роботи програми

count = 4
Items of one-dimensional array:
97     40     23     95
Enter the size of array:
m = 5
n = 6
Items of two-dimensional array:
9       64     86     64     27       55
59     38     100     4       3       74
26     25     22     7       45     62
89     84     48     48     79       56
79     42     49     70     7       73

 


Зв’язані теми