Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Липпман.doc
Скачиваний:
8
Добавлен:
14.08.2019
Размер:
7.54 Mб
Скачать

15.11. Разрешение перегрузки и функции-члены a

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

  1. Отбор функций-кандидатов.

  2. Отбор устоявших функций.

  3. Выбор наилучшей из устоявших функции.

Однако есть небольшие различия в алгоритмах формирования множества кандидатов и отбора устоявших функций-членов. Эти различия мы и рассмотрим в настоящем разделе.

15.11.1. Объявления перегруженных функций-членов

Функции-члены класса можно перегружать:

class myClass {

public:

void f( double );

char f( char, char ); // перегружает myClass::f( double )

// ...


};

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

class myClass {

public:

void mf();

double mf(); // ошибка: так перегружать нельзя

// ...


};

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

class myClass {

public:

void mf();

void mf(); // ошибка: повторное объявление

// ...


};

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

Множество перегруженных функций-членов может содержать как статические, так и нестатические функции:

class myClass {

public:

void mcf( double );

static void mcf( int* ); // перегружает myClass::mcf( double )

// ...


};

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

15.11.2. Функции-кандидаты

Рассмотрим два вида вызовов функции-члена:

mc.mf( arg );


pmc->mf( arg );

где mc – выражение типа myClass, а pmc – выражение типа “указатель на тип myClass”. Множество кандидатов для обоих вызовов составлено из функций, найденных в области видимости класса myClass при поиске объявления mf().

Аналогично для вызова функции вида

myClass::mf( arg );

множество кандидатов также состоит из функций, найденных в области видимости класса myClass при поиске объявления mf(). Например:

class myClass {

public:

void mf( double );

void mf( char, char = '\n' );

static void mf( int* );

// ...

};

int main() {

myClass mc;

int iobj;

mc.mf( iobj );


}

Кандидатами для вызова функции в main() являются все три функции-члена mf(), объявленные в myClass:

void mf( double );

void mf( char, char = '\n' );


static void mf( int* );

Если бы в myClass не было объявлено ни одной функции-члена с именем mf(), то множество кандидатов оказалось бы пустым. (На самом деле рассматривались бы также и функции из базовых классов. О том, как они попадают в это множество, мы поговорим в разделе 19.3.) Если для вызова функции не оказывается кандидатов, компилятор выдает сообщение об ошибке.