Мова С++ надає можливість використовувати однакові імена для декількох функцій. Звичайно різні функції мають різні імена, але інколи виникає потреба у тому, щоб одна функція виконувала схожі дії над об’єктами різних типів. У цьому випадку є сенс визначити декілька функцій з однаковим іменем, але різним тілом. Такі функції повинні мати набори аргументів, які відрізняються, для того щоб компілятор міг їх розпізнавати. В цьому випадку йде мова про перевантаження функцій. Головна перевага перевантажених функцій — це можливість визначання кількох функцій з однаковим іменем, але з різними типами або числом параметрів, при цьому тип результату, що повертається, може не змінюватись.
Приклад 9.10. Написати приклад програмної реалізації а використанням перевантаження функцій.
// Р9_10.СРР — использование перегрузки фунщий
#include <iostream.h>
#include <string.h>
#include <conio.h>
int funp(int x) //------- 1-я функция
{ return x*x; }
int funp(unsigned x) //------- 2-я функция
{ return -x*x; }
char funp(char x) //------- 3-я функция
{ return x+3; }
int funp(int x, char *y) //------- 4-я функция
{ return x*strlen(y); }
int funp(int x, char у) //------- 5-я функция
{ return x*y; }
float funp(float r) //------- 6-я функция
{ return r*r; }
float funp(double r) //------- 7-я функция
{ return r+r; }
main ( )
{
cout << funp(5) << endl; //результат 25
cout << funp((unsigned)10) << endl; //результат -100
cout << funp('a') << endl; //результат у
cout << funp(4,"abc") << endl; //результат 12
cout << funp(4, 'a') << endl; //результат -128
cout << funp((float) 1.2) << endl; //результат 1.44
cout << funp((double) 4.5) << endl; //результат 9
getch();
return 0;
}
Процес пошуку відповідної функції із багатьох перевантажених полягає в знаходженні найкращого співвідношення типів формальних та фактичних параметрів.
Приклад 9.11. З використанням перевантаження функцій написати програму обчислення площі квадрата, прямокутника та трикутника.
/* Р9_11.СРР — вычисления площадей квадрата, прямоугольника и треугольника с использованием перегрузки функций */
#inchide <iostream.h>
#include <conio.h>
int sfig(int a) // функция вычисления площади квадрата
{ return а*а; }int sfig (int a, int b) // функция вычисления площади прямоугольника
{ return a*b; }float sfig(int a, float h) //функция вычисления площади треугольника
{ return a*h/2;}
void main()
{
int a, b;
float h;
//------------------- ввод стороны квадрата и вычисление площади
cout << "Vvedite storonu kvadrata\n ";
сіn >> a;
cout << "s=" << sfig (a) << "\n";
//--------------- ввод сторон прямоугольника и вычисление площади
cout << "Vvedite storony pijamougolnika\n ";
сіn >> a >> b;
cout <<"s=" << sfig (a,b) << "\n";
//---- ввод основания и высоты треугольника и вычисление площадиcout << "Vvedite storony і vysotu treugo!nika\n ";
сіn >> a >> h;
cout << "s=" << sfig (a,h) << "\n";
getch ();
}
У наведеній програмі перша функція відрізняється від інших кількістю параметрів, а друга і третя функції — типом параметрів та типом результату.
Використовуючи перевантажені функції, треба бути уважними з числовимиаргументами-константами. Наприклад, якщо обчислюючи площу трикутника, визвати функцію таким чином:
cout<<“s=”<<sfig (4,3)<< “\n”;
то одержимо площу прямокутника, бо «3» — константа типу int, а потрібно float:
cout<<“s=”<<sfig (4,3.0)<< “\n”;
або
cout<<“s=”<<sfig (4,(float)3)<< “\n”;
У процесі розв’язання багатьох задач необхідно використовувати функції, в яких алгоритм обчислення однаковий, а типи даних відрізняються. Прикладом є задачі пошуку і сортування. Особливістю програмування таких задач мовою С++ є використання шаблонів функцій.
Шаблони функцій — потужний засіб параметризації. За допомогою шаблона функції можна визначити алгоритм, який буде застосовуватися до даних різних типів, а конкретний тип даних передається функції у вигляді параметра на етапі компіляції.
Шаблон функції — це деяка узагальнена функція (родова функція) для сімейства функцій, призначених для розв’язання даної задачі. Визначається така шаблонна функція у заголовочному файлі і має такий вигляд:
template <class Т>
type_func my_func (type paraml, type param2, …)
{
// операторы тела функции
}
де template <class T> — зарезервований вираз (заголовок шаблону), який вказує компілятору оголошений користувачем ідентифікатор типу Т;
type_func — тип шаблонної функції;
my_func — довільний ідентифікатор шаблонної функції;
type param1, type param2 — формальні параметри, з яких хоча б один повинен мати або наведений у заголовку (template cclass type>) тип Т, або покажчик *param на змінну типу Т (Т *param), або посилання ¶m на змінну типу Т (Т ¶m);
оператори тіла функції — схема реальних операторів, що генеруються компілятором у відповідну функцію, враховуючи тип даних, вказаних при виклику.
У шаблоні функції може бути оголошено декілька формальних типів даних, а також використано параметри означених раніше типів. Наприклад:
template <class ТІ, class T2>
typefunc my_func(Ti a,double x,T2 b,int c.char s)
{
//операторы тела функции
}
Таким чином, оголошення шаблонів функцій завжди починається з ключового словаtemplate (шаблон), за ним у кутових дужках визначається список формальних типів, перед кожним з яких вказується ключове слово class (поняття класу розглянуто у розділі 11.1).Далі йде звичайний опис функції. При цьому формальні типи, представлені у заголовку шаблону, можна використовувати в опису функції для задання типів аргументів функції, типу значення, що повертається, а також для оголошення змінних усередині тіла функції.
Приклад 9.12. Написати шаблон функції, що повертає мінімальний елемент масиву, застосувати цю функцію для обробки масивів різних типів.
/* Р912.СРР — использование шаблона функции для вычисления минимального элемента массивов разных типов */
#include <iostream.h>
#include <conio.h>//--------------------------------------------- шаблон функции
template <class T> T minmas (Т *а, int k)
{ Т min = a[0];
for (int і = 1; і < k; i++)
if (a[i] < min) min = a[i];
return min;
}
//--------------------------------------------- главная функция
void main()
{int b[ ]={1, 6, 8, 5, 9, -6, 4, -5, 2;//целочисленный массив
//---------------- вызов функции minmas() и вывод результатов
cout <<" min массива в[ ]= "<<minmas(b, sizeof(b)/sizeof(int));
cout << endl;
float c[ ]={-4.5, 6.4, 7.0, -6.3, 2.1};
//массив вещественных чисел
cout <<" min массива c[ ]= "<<minmas(c, sizeof(c)/sizeof(float));
getch();
}
Результат обчислень:
min массива в[ ]=-6
min массива с[ ]=-6.3
У заголовку шаблону цієї функції оголошено єдиний формальний параметр Т як тип даних, що повинні оброблятися функцією minmas(). У заголовку функції параметр Т використовується для задания типу значення функції, що повертається (Т minmas), та для задання типу показчика *а. Усередині функції параметр Т застосовано для визначення типу локальної змінної тіл. Завдяки цьому шаблону у програмі можна обробляти масиви різних типів.
програмування