Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
samples / Zaochniki / ООП.doc
Скачиваний:
28
Добавлен:
25.03.2015
Размер:
183.81 Кб
Скачать

№9 Перегрузка и переопределение членов класса

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

Почему следует использовать перегрузку

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

а = b if а = b ...

Перегрузка, распространяясь на концептуально сходные операции, придает C++ особую гибкость, предостав­ляя тем самым возможность пользователям писать программы с меньшими усилиями. Достоинства перегрузки не достаются даром, и они повышают сложность компилятора, которому теперь при­ходится больше "думать". Однако точ­ное значение перегруженного идентификатора можно понять только после рассмотрения нескольких соседних слов. В C++ соседними словами являются количество и тип аргументов, используемых при вызове функции. Таким об­разом, перегрузка применима только к функциям, но не к переменным, классам или типам. Две функции void Display(int); и long Display(int); не различимы и приведут к ошибке компиляции. Перегруженные функции вовсе не обязательно должны быть чле­нами класса. Можно перегружать как функции-члены, так и обычные функции.

Перегруженные функции - не члены

В C++ перегружается любое имя функции, но перегрузка происходит только внутри определенной области ви­димости. Одна из них — область видимости файла. Любая функция, определенная вне всех классов и без ключевого слова static, имеет область видимости файла. В следующем примере кода используются перегруженные функции Di splay ( ), которые находятся внутри одного и того же файла и имеют область видимости файла:

#include <stdio.h>

void Display (char* string) { puts(string); }

void Display (longvalue) { printf("%ld", value); }

void Display (double value) { printf("%lf, value); }

void main( )

{Display ("\nНапечатай это, пожалуйста");

Display (123456789) ;

Display (3.14159) ;}

Когда компилятор видит различные обращения к Display ( ), он ищет подходящую для использования функ­цию. Результат такого поиска затем отражается в откомпилированном коде. Вся дополнительная работа выпол­няется во время компиляции, что очень важно. Это говорит о том, что во время выполнения программы дополни­тельных затрат не требуется. После создания исполняемого кода обращение к перегруженной функции уже ничем не отличается от обращения к любой другой функции. Так что пользователь имеет все преимущества, связанные с унифицированностью выражений, и не имеет никаких неудобств при увеличении исполняемого кода или затрат времени. Однако сложность выполняемого кода все-таки возрастает, если перегруженная функция вызывается с аргументами, не вполне подходящими любой до­ступной функции. В таком случае следует быть особенно внимательным. Дело может закончиться ошибкой компи­ляции или вызовом не той функции.

Перегруженные функции-члены

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

class Example {

int value;

public:

void Value(int v) { value = v; }

int Valued { return value; }

};

void main( )

{Example e;

e.Value (3) ;

int i = e.Value ( ) ;

Код показывает, что класс Example имеет две перегруженные функции, одну — для записи, а другую — для чтения переменной. Для перегруженных функций это обычное явление. В ANSI С пришлось бы использовать две отдельные функции, такие как putValue ( ) и getValue ( ). C++ позволяет это упростить. Перегруженные функ­ции не обязательно должны быть определены подставляемыми, как показано в примере. Однако типичные функ­ции на чтение и запись переменных определяются именно так. Перегруженные функции должны отличаться по од­ному или обоим описанным ниже пунктам.

1. Функции должны имеет разное количество аргументов.

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

Соседние файлы в папке Zaochniki