Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP.DOC
Скачиваний:
13
Добавлен:
03.05.2019
Размер:
618.5 Кб
Скачать

3. Перегрузка

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

Перегрузка не является атрибутом именно объектно-ориентиро­ванного программирования и может использоваться и в традиционных программах. Однако для ООП перегрузка является одним из краеугольных камней; многие фундаментальные методики ООП целиком основаны на этом понятии.

Перегрузка функций

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

void Func(int);

void Func(int,int);

void Func(char*);

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

void Func(int);

int Func(int);

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

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

void Func(int); @MyClass@Func$qi

void Func(int,int); @MyClass@Func$qii

void Func(char*); @MyClass@Func$qpzc

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

Рассмотрим пример перегрузки функций-членов класса, воспользовавшись нашим простым классом Men:

class Men{

char* name;

int age;

public:

Men(char n,int a){name=n;age=a;}//Конструктор

void Age(int a){age=a;}//Запись возраста

int Age(){return age;}//Чтение возраста

};

Теперь и для инициализации, и для чтения переменной age мы используем один идентификатор Age(), хотя, в зависимости от состава используемых аргументов, он обозначает разные функции:

Men* pm = new Men("Орлов",18);//Вызов конструктора

pm->Age(19);// Коррекция возраста

int a = pm->Age();//Чтение возраста

Во втором предложении этого фрагмента функция Age() вызывается с целочисленным аргументом (типа int), и компилятор обращается к функции для записи возраста; в третьем предложении функция Age() вызывается без аргумента, и компилятор подставляет в программу вызов функции для чтения возраста.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]