|
Программирование >> Инициализация объектов класса, структура
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 & ); Однако все они делают одно и то же: возвращают наибольшее из значений параметров. С точки зрения пользователя, здесь лишь одна операция - вычисление максимума, а детали ее реализации большого интереса не представляют. Отмеченная лексическая сложность отражает ограничение программной среды: всякое имя, встречающееся в одной и той же области видимости, должно относиться к уникальной сущности (объекту, функции, классу и т.д.). Такое ограничение на практике создает определенные неудобства, поскольку программист должен помнить или каким-то образом отыскивать все имена. Перегрузка функций помогает справиться с этой проблемой. Применяя перегрузку, программист может написать примерно так: vector<int> vec; ... int ix = max( j, k ); int iy = max( vec ); Этот подход оказывается чрезвычайно полезным во многих ситуациях. 9.1.2. Как перегрузить имя функции В C++ двум или более функциям может быть дано одно и то же имя при условии, что их списки параметров различаются либо числом параметров, либо их типами. В данном int max ( int, int ); int max( const vector<int> & ); примере мы объявляем перегруженную функцию max() : int max( const matrix & ); Для каждого перегруженного объявления требуется отдельное определение функции max() с соответствующим списком параметров. Если в некоторой области видимости имя функции объявлено более одного раза, то второе (и последующие) объявление интерпретируется компилятором так: если списки параметров двух функций отличаются числом или типами / / перегруженнхе функции void print( const string & ); параметров, то функции считаются перегруженными: void print( vector<int> & ); объявления одной и той же функции void print( const string &str ); функций одинаковы, то второе объявление считается повторным: void print( const string & ); Имена параметров при сравнении объявлений во внимание не принимаются; если списки параметров двух функций одинаковы, но типы возвращаемых значений различны, то второе объявление считается неправильным (несогласованным с первым) и unsigned int max( int i1, int i2 ); int max( int i1, int i2 ); ошибка: отличаются только тип1 помечается компилятором как ошибка: возвращаема значений Перегруженные функции не могут различаться лишь типами возвращаемого значения; если списки параметров двух функций разнятся только подразумеваемыми по объявления одной и той же функции int max ( int *ia, int sz ) ; умолчанию значениями аргументов, то второе объявление считается повторным: int max ( int *ia, int = 10 ); Ключевое слово typedef создает альтернативное имя для существующего типа данных, новый тип при этом не создается. Поэтому если списки параметров двух функций различаются только тем, что в одном используется typedef, а в другом тип, для которого typedef служит псевдонимом, такие списки считаются одинаковыми, как, например, в следующих двух объявлениях функции calc() . В таком случае второе объявление даст ошибку компиляции, поскольку возвращаемое значение отличается от указанного typedef не вводит нового типа typedef double DOLL; / / ошибка: одинаковые списки параме тров, но разные тип1 возвращаема значений extern DOLL calc ( DOLL ); раньше: extern int calc( double ); Спецификаторы const или volatile при подобном сравнении не принимаются во внимание. Так, следующие два объявления считаются одинаковыми: если тип возвращаемого значения и списки параметров в объявлениях двух
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |