Перевантаження і шаблони функцій

Мова С++ надає можливість використовувати однакові іме­на для декількох функцій. Звичайно різні функції мають різні імена, але інколи виникає потреба у тому, щоб одна функція виконувала схожі дії над об’єктами різних типів. У цьому випадку є сенс визначити декілька функцій з однаковим іменем, але різним тілом. Такі функції повинні мати набори аргумен­тів, які відрізняються, для того щоб компілятор міг їх розпізнавати. В цьому випадку йде мова про перевантаження функ­цій. Головна перевага перевантажених функцій — це мож­ливість визначання кількох функцій з однаковим іменем, але з різними типами або числом параметрів, при цьому тип ре­зультату, що повертається, може не змінюватись.

Приклад 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), або посилання &param на змінну типу Т (Т &param);

оператори тіла функції — схема реальних операторів, що ге­неруються компілятором у відповідну функцію, враховуючи тип даних, вказаних при виклику.

У шаблоні функції може бути оголошено декілька формаль­них типів даних, а також використано параметри означених раніше типів. Наприклад:

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), та для задання типу показчика *а. Усередині функції параметр Т застосовано для визначення типу локальної змінної тіл. Завдяки цьому шаблону у програмі можна оброб­ляти масиви різних типів.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *