Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C++ для начинающих (Стенли Липпман) 3-е хххх.pdf
Скачиваний:
84
Добавлен:
30.05.2015
Размер:
5.92 Mб
Скачать

С++ для начинающих

435

(a)int calc( int, int );

int calc( const int, const int );

(b)int get(); double get();

(c)int *reset( int * ); double *reset( double * ):

(d)extern "C" int compute( int *, int );

extern "C" double compute( double *, double );

Упражнение 9.4

(a)void reset( int * );

void (*pf)( void * ) = reset;

(b)int calc( int, int );

int (*pf1)( int, int ) = calc;

(c)extern "C" int compute( int *, int ); int (*pf3)( int*, int ) = compute;

Какая из следующих инициализаций приводит к ошибке? Почему?

(d)void (*pf4)( const matrix & ) = 0;

9.2.Три шага разрешения перегрузки

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

T t1, t2;

void f( int, int ); void f( float, float );

int main() { f( t1, t2 ); return 0;

вызове аргументах. Рассмотрим пример:

}

Здесь в ходе процесса разрешения перегрузки в зависимости от типа T определяется,

будет ли при обработке выражения f(t1,t2) вызвана функция f(int,int) или f(float,float) или зафиксируется ошибка.

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

С++ для начинающих

436

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

Процесс разрешения перегрузки функции состоит из трех шагов, которые мы покажем на

void f(); void f( int );

void f( double, double = 3.4 ); void f( char *, char * );

void main() { f( 5.6 ); return 0;

следующем примере:

}

При разрешении перегрузки функции выполняются следующие шаги:

1.Выделяется множество перегруженных функций для данного вызова, а также свойства списка аргументов, переданных функции.

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

3.Находится функция, которая лучше всего соответствует вызову.

Рассмотрим последовательно каждый пункт.

На первом шаге необходимо идентифицировать множество перегруженных функций, которые будут рассматриваться при данном вызове. Вошедшие в это множество функции называются кандидатами. Функция-кандидат это функция с тем же именем, что и вызванная, причем ее объявление видимо в точке вызова. В нашем примере есть четыре таких кандидата: f(), f(int), f(double, double) и f(char*, char*).

После этого идентифицируются свойства списка переданных аргументов, т.е. их количество и типы. В нашем примере список состоит из двух аргументов типа double.

На втором шаге среди множества кандидатов отбираются устоявшие (viable) – такие, которые могут быть вызваны с данными аргументами, Устоявшая функция либо имеет столько же формальных параметров, сколько фактических аргументов передано вызванной функции, либо больше, но тогда для каждого дополнительного параметра должно быть задано значение по умолчанию. Чтобы функция считалась устоявшей, для любого фактического аргумента, переданного при вызове, обязано существовать преобразование к типу формального параметра, указанного в объявлении.

В нашем примере есть две устоявших функции, которые могут быть вызваны с приведенными аргументами:

функция f(int) устояла, потому что у нее есть всего один параметр и

существует преобразование фактического аргумента типа double к формальному параметру типа int;

функция f(double,double) устояла, потому что для второго аргумента есть значение по умолчанию, а первый формальный параметр имеет тип double, что в точности соответствует типу фактического аргумента.

Если после второго шага не нашлось устоявших функций, то вызов считается ошибочным. В таких случаях мы говорим, что имеет место отсутствие соответствия.