prosdo.ru
добавить свой файл
1

Лабораторная работа №1. Перегрузка функций. Шаблоны функций


1 Цель работы

Цель работы – изучить определение и варианты использования перегрузки функций и шаблонов функций в языке С++.
2 Порядок выполнения работы


  • ознакомиться с описанием лабораторной работы;

  • получить задание у преподавателя по вариантам;

  • разработать и отладить программу;

  • составить и защитить отчет по лабораторной работе у преподавателя.


3 Содержание отчета

  • титульный лист;

  • краткое теоретическое описание;

  • задание на лабораторную работу, включающее математическую формулировку задачи;

  • результаты выполнения работы, включающие схему алгоритма, тексты программ, результаты вычислений;


4 Краткая теория

4.1 Перегрузка функций

С++ позволяет определить несколько функций с одним и тем же именем, если эти функции имеют разные наборы параметров (по меньшей мере разные типы параметров). Эта особенность называется перегрузкой функции. При вызове перегруженной функции компилятор С++ определяет соответствующую функцию путем анализа количества, типов и порядка следования аргументов в вызове. Перегрузка функции обычно используется для создания нескольких функций с одинаковым именем, предназначенных для выполнения сходных задач, но с разными типами данных.

Перегруженные функции различаются компилятором с помощью их сигнатуры – комбинации имени функции и типов ее параметров. Компилятор кодирует идентификатор каждой функции по числу и типу ее параметров, чтобы иметь возможность осуществлять надежное связывание типов. Надежное связывание типов гарантирует, что вызывается надлежащая функция и что аргументы согласуются с параметрами.

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

double multy(double x) {return x*x*x;}

double multy(double x, double y) {return x*y*y;}

double multy(double x, double y, double z)

{return x*y*z;}
Каждое из следующих обращений к функции multy() будет однозначно идентифицировано и правильно обработано:
multy(0.4)

multy(4.0,12.3)


multy(0.1e-6,1.2e4,6.4)
Однако добавление в программу такой функции прототипа с начальными значениями параметров:
double multy(double a=1.0, double b=1.0,

double c=1.0, double d=1.0)

{return a*b+c*d;}
навсегда запутает любой компилятор при попытках обработать, например, такой вызов:
multy(0.1e-6,1.2e4)
4.2 Шаблоны функций

Перегруженные функции обычно используются для выполнения сходных операций над различными типами данных. Если операции идентичны для каждого типа, это можно выполнить более компактно и удобно, используя шаблоны функций. Достаточно написать одно единственное определение шаблона функции. Основываясь на типах аргументов, указанных в вызовах этой функции, С++ автоматически генерирует разные функции для соответствующей обработки каждого типа. Таким образом, определение единственного шаблона определяет целое семейство решений.

Все определения шаблонов функций начинаются с ключевого слова template, за которым следует список формальных параметров функции, заключенный в угловые скобки (<) и (>). Каждый формальный тип параметра предваряется служебным словом class. Формальные типы параметров – это встроенные типы или типы, определяемые пользователем. Они используются для задания типов аргументов функции, для задания типов возвращаемого значения функции и для объявления переменных внутри тела функции. После шаблона следует обычное описание функции. Пример определения шаблон функций, вычисляющих абсолютные значения числовых величин разных типов:

template

type abs (type x) { return x>0 ? x: -x; }
Шаблон семейства функций состоит из двух частей – заголовка шаблона:
template <список_параметров_шаблона>
и из обыкновенного определения функции. Имена параметров шаблона могут использоваться и в теле определения функции для обозначения типов локальных объектов.

По существу, механизм шаблонов функций позволяет автоматизировать подготовку определений перегруженных функций. При использовании шаблонов уже нет необходимости готовить заранее все варианты функций с перегруженным именем. Компилятор автоматически, анализируя вызовы функций в тексте программы, формирует необходимые определения именно для таких типов параметров, которые использованы в обращениях. Дальнейшая обработка выполняется так же, как и для перегруженных функций.




Рисунок 2 – Схема параметризации шаблона функций
Можно считать, что параметры шаблона функций являются формальными параметрами, а типы тех параметров, которые используются в конкретных обращениях к функции, служат фактическими параметрами шаблона. Именно по ним выполняется параметрическая настройка и с учетом этих типов генерируется конкретный текст определения функции (см. рис. 2).

Перечислим основные свойства параметров шаблона.


  1. Имена шаблона должны быть уникальными во всем определении шаблона.

  2. Список параметров шаблона не может быть пустым, так как при этом теряется возможность параметризации и шаблон функций становится обычным определением конкретной функции.

  3. В списке параметров шаблона функции может быть несколько параметров. Каждый из них должен начинаться служебным словом class. Например, допустим такой заголовок шаблона:


template
Соответственно, неверен заголовок:

template



  1. Недопустимо использовать в заголовке шаблона параметры с одинаковыми именами, т.е. ошибочен такой заголовок:


template


  1. Имя параметра шаблона имеет в определяемой шаблоном функции все права имени типа, т.е. с его помощью могут специализироваться формальные параметры, определяться тип возвращаемого функцией значения и типы любых объектов, локализованных в теле функции. Имя параметра шаблона видно во всем определении и скрывает другие использования того же идентификатора в области, глобальной по отношению к данном шаблону функции. Все параметры шаблона функций должны быть обязательно использованы в спецификациях параметров определения функции. Определяемая с помощью шаблона функция может иметь любое количество непараметризованных формальных параметров. Может быть не параметризовано и возвращаемое функцией значение. При использовании шаблонов функций возможна перегрузка как шаблонов, так и функций. Могут быть шаблоны с одинаковыми именами, но разными параметрами. Или с помощью шаблона может создаваться функция с таким же именем, что и явно определенная функция. В обоих случаях «распознавание» конкретного вызова выполняется по сигнатуре, т.е. по типам, порядку и количеству фактических параметров.

5 Примеры программ

1. Перегрузить функцию, возвращающую максимальное из значений элементов одномерного массива, передаваемого ей в качестве параметра. Массивов могут быть типов: int, long, float, double.
#include

//функция для массивов с элементами типа int

long max_elem(int n,int array[])

{

int value=array[0];

for (int i=1;i

value=value>array[i]?value:array[i];

cout<<"\nДля (int) : ";

return long(value);

}

//функция для массивов с элементами типа long


long max_elem(int n,long array[])

{

long value=array[0];

for (int i=1;i

value=value>array[i]?value:array[i];

cout<<"\nДля (long) : ";

return value;

}

//функция для массивов с элементами типа float

double max_elem(int n,float array[])

{

float value=array[0];

for (int i=1;i

value=value>array[i]?value:array[i];

cout<<"\nДля (float) : ";

return double(value);

}

//функция для массивов с элементами типа double

double max_elem(int n,double array[])

{

double value=array[0];

for (int i=1;i

value=value>array[i]?value:array[i];

cout<<"\nДля (double): ";

return value;

}

void main()

{

int x[]={10,20,30,40,50,60};

long f[]={12l,44l,5l,22l,37l,30l};

float y[]={0.1,0.2,0.3,0.4,0.5,0.6};

double z[]={0.01,0.02,0.03,0.04,0.05};

cout<<"max_elem(6,x)="<

cout<<"max_elem(6,f)="<

cout<<"max_elem(6,y)="<

cout<<"max_elem(5,z)="<

}
Результат работы программы:
Для (int) : max_elem(6,x)=60

Для (long) : max_elem(6,f)=44

Для (float) : max_elem(6,y)=0.6

Для (double): max_elem(5,z)=0.05
2. Определить семейство функций, каждая из которых подсчитывает количество нулевых элементов одномерного массива параметризованного типа.
#include

template

long count0(int, D*); //прототип шаблона

void main()

{

int A[]={1,0,6,0,4,10};

int n=sizeof(A)/sizeof A[0];

cout<<"\ncount0(n,A)="<

float X[]={10.0,0.0,3.3,0.0,2.1};

n=sizeof(X)/sizeof X[0];

cout<<"\ncount0(n,X)="<

}

//шаблон функций для подсчета количества нулей в массиве

template

long count0(int size, T* array)

{

long k=0;

for (int i=0;i

if (int(array[i])==0) k++;

return k;

}
Результат выполнения программы:

count0(n,A)=2

count0(n,X)=2

6 Контрольные вопросы


  1. Как и с какой целью используется перегрузка функций?

  2. Каким образом выполняется распознавание перегруженных функций при их вызове?

  3. Можно ли при использовании перегруженных функций задавать начальные значения их параметров?

  4. Каким образом описывается шаблон семейства функций?

  5. Опишите схему параметризации шаблона функций.

  6. Перечислите основные свойства параметров шаблона.

  7. Может ли созданная с помощью шаблона функция иметь то же имя, что и явно определенная функция?


7 Варианты заданий для самостоятельного решения

1. Перегрузить функцию add для суммирования одномерных массивов типа int и float и сцепления строк.

2. Описать шаблон функции, которая меняет местами минимальный и максимальный элементы массива.

3. Перегрузить функцию area, вычисляющую площадь круга по его радиусу, прямоугольника и треугольника по их сторонам.

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


5. Перегрузить функцию perimetr, вычисляющую периметр круга по его радиусу, прямоугольника и треугольника по их сторонам.

6. Разработать шаблон функции, формирующей новый массив, упорядоченный по неубыванию, из двух массивов-параметров, уже упорядоченных по неубыванию.

7. Перегрузить функции input и output для ввода и вывода на экран массивов и матриц.

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

9. Перегрузить функцию distance вычисления расстояния между двумя точками в двумерном и трехмерном пространстве.

10. Разработать шаблон функции сортировки элементов массива методом пузырька.

11. Перегрузить функцию min_el поиска минимального элемента в массивах и матрицах различного типа.

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

13. Перегрузить функцию null_count определения количества нулей в массивах и матрицах различного типа.

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

15. Перегрузить функцию movement определения пройденного расстояния при равномерном и равноускоренном движениях тела.

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

17. Перегрузить функцию triangle вычисления площади треугольников: равностороннего (по стороне), равнобедренного (по основанию и высоте), обычного (по трем сторонам).

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

19. Перегрузить функцию volume определения объемов: шара по его радиусу (V=4/3R2), конуса по радиусу основания и высоте (V=1/3r2h), усеченного конуса по радиусам двух оснований и высоте (V=1/3h(r2+r12+rr1)).


20. Разработать шаблон функции, находящей среднее арифметическое элементов массива.

21. Перегрузить функции: generate заполнения массивов и матриц случайными числами заданного диапазона и output вывода их на экран.

22. Описать шаблон функции, которая считает сумму элементов главной диагонали матрицы.

23. Перегрузить функцию surface_area определения площади поверхности: шара по его радиусу (S=4R2), цилиндра по радиусу основания и высоте (S=2r(r+h)), усеченного конуса по радиусам двух оснований и образующей (S=((r+r1)+r2+r12)).

24. Описать шаблон функции, находящей среднеквадратическое значение элементов матрицы.

25. Перегрузить функцию mult умножения массива и матрицы на число.

26. Разработать шаблон функции сложения двух матриц.

27. Перегрузить функцию sub_array нахождения разности двух массивов и матриц.

28. Описать шаблон функции, подсчитывающей количество строк матрицы, сумма элементов которых больше некоторого заданного числа (это число имеет тот же тип, что и элементы матрицы).