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

9. Перегруженные функции

Итак, мы уже знаем, как объявлять, определять и использовать функции в программах. В этой главе речь пойдет об их специальном виде – перегруженных функциях. Две функции называются перегруженными, если они имеют одинаковое имя, объявлены в одной и той же области видимости, но имеют разные списки формальных параметров. Мы расскажем, как объявляются такие функции и почему они полезны. Затем мы рассмотрим вопрос об их разрешении, т.е. о том, какая именно из нескольких перегруженных функций вызывается во время выполнения программы. Эта проблема является одной из наиболее сложных в C++. Тем, кто хочет разобраться в деталях, будет интересно прочитать два раздела в конце главы, где тема преобразования типов аргументов и разрешения перегруженных функций раскрывается более подробно.

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

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

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

1 + 3

вызывается операция целочисленного сложения, тогда как вычисление выражения

1.0 + 3.0

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

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

9.1.1. Зачем нужно перегружать имя функции

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

int i_max( int, int );

int vi_max( const vector<int> & );


int matrix_max( const matrix & );

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

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

Применяя перегрузку, программист может написать примерно так:

int ix = max( j, k );

vector<int> vec;

//...


int iy = max( vec );

Этот подход оказывается чрезвычайно полезным во многих ситуациях.