- •Указатели на функции
- •Тип функции (* имя указателя) (спецификация параметров)
- •Int * ( * fptr ) ( char * , int );
- •Int (*ptr) (char*);
- •Имя_ указателя (список фактических параметров); (* имя указателя) (список фактических параметров);
- •Int len (char* e) {
- •Int main (){
- •Int (*ptr) (char*); //объявлен указатель на функцию
- •Массивы указателей на функции
- •Float ( * ptrArray [ 4 ] ) ( char , int ) ;
- •Определение типа указателя на функцию
- •Typedef int (* ptr) ( int);
- •Typedef void (* ptf ) ( ptr , int , char*);
- •Int main () { int n;
- •Void table ( func ptrA [ ] , int n, float xn , float xk , float dx )
- •Int main () {
- •Void main ( )
- •Ссылка на функцию Определение:
- •Void main ( )
- •Void (*pf) (char) (func) ;
- •Void (& rf)(char)( func ); Ссылка - возвращаемый результат функции
- •Return имя переменной;
- •Int & rmax ( int n , int d [ ] )
- •Void main ()
- •Рекурсивные функции
- •Шаблоны функций
- •Void swap (t&X, t&y)
- •Void swap (long &X, long &y) //2
- •Void swap (double &X, double &y) //3
- •Void main()
- •Свойства:
- •B func ( a r, c t ) { b V; …} -ошибка
- •Перегрузка функций
- •Void f (int);
- •Void f (int, int);
- •Void f (char*);
- •Void main ()
- •Подставляемые функции
- •Inline float Line(float x1,float y1,float x2, float y2)
Шаблоны функций
Шаблон семейства функций – это конструкция, позволяющая автоматически создавать функции, обрабатывающие разные типы данных.
Шаблон семейства функций определяется один раз, но это определение параметризуется.
Параметрами в шаблоне могут быть типы любых параметров функций и тип возвращаемого функцией значения.
Для параметризации используется список формальных параметров шаблона, который следует после слова template, заключенный в угловые скобки < >.
Каждый параметр обозначается словом class, за которым следует имя параметра. Имя параметра – это название типа, его можно использовать для обозначения типов параметров функции, типа возвращаемого результата и для объявления типов локальных переменных функции.
Примеры определения шаблонов функций:
template <class T>
Void swap (t&X, t&y)
{ T z = x; x = y; y = z; }
template <class R>
R abs ( R x) { return x>0 ? x : -x;}
Если далее в программе обнаруживаются вызовы функций с данными именами, компилятор определяет соответствующие нужные функции.
…
abs(-45.8); //1
long a=4, b=5;
swap(a, b); //2
double c=3.8, d=6.8;
swap(c, d); //3
…
компилятор сформирует следующие определения функций:
double abs ( double x) { return x>0 ? x : -x;} //1
Void swap (long &X, long &y) //2
{ long z = x; x = y; y = z; }
Void swap (double &X, double &y) //3
{ double z = x; x = y; y = z; }
Еще один шаблон семейства функций, возвращающих наибольший элемент массива (но не значение, а участок памяти, т.е. возвращается ссылка):
template <class type>
type & max ( int n , type A[ ] )
{ int imax =0;
for(int i=1 ; i< n ; i++)
if ( A[imax] < A[i] ) imax = i;
return A[imax];
}
Void main()
{int x[4] = {…};
float y[3] = { …};
cout<< max ( 4, x) << max (3, y);
}
Свойства:
имя параметра уникально в шаблоне;
список параметров шаблона не может быть пустым;
каждый параметр обязательно определяется со словом class;
все параметры шаблона должны обязательно быть использованы в спецификации параметров функции?
template <class A, class B, class C>
B func ( a r, c t ) { b V; …} -ошибка
Шаблоны служит для автоматического формирования конкретных определений функций по тем вызовам, которые транслятор обнаруживает в тексте программы.
В зависимости от вызовов создает определения функций, обрабатывающих данные различных типов.
Перегрузка функций
С++ позволяет определить в программе произвольное количество функций с одним именем, при условии, что все они имеют разный состав параметров, или сигнатуру:
Void f (int);
Void f (int, int);
Void f (char*);
При вызове перегруженной функции компилятор анализирует ее сигнатуру и выбирает из списка одноименных функций ту функцию, сигнатура которой соответствует вызываемой.
При этом для перегрузки возвращаемый функцией тип значения не имеет, функции:
void F (int),
int F (int)
не являются перегруженными, компилятор их не различает и будет выведена ошибка при определении второй функции.
Для того чтобы различать одноименные функции компилятор использует кодирование имен функций (создает уточненные имена). Функциям даются имена, в которые входят имя класса, если эта функция компонентная, имя функции и список обозначений типов параметров.
class MyClass {…
void Func (int); //@MyClass@Func$qi
void Func (int, int); //@MyClass@Func$qii
void Func (char*); //@ MyClass@Func$qpz
…};
Пример перегрузки глобальных функций:
#include<iostream.h>
void Print ( int i) { cout << "\n int = " <<i;}
void Print ( int*pi ) { cout<<"\n pointer = " << pi << ", значение = " << *pi;}
void Print ( char*s) { cout << "\n string = " <<s;}
