Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по Технологии разработки ПО 2005.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
833.54 Кб
Скачать

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

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

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

class Stack {

protected:

enum { MAX = 3 }; // размер стека

int st[MAX]; // данные, хранящиеся в стеке

int top; // индекс последнего элемента в стеке

public:

Stack( ) // конструктор

{ top = -1; }

void push(int var) // помещение числа в стек

{ st[++top] = var; }

int pop( ) // извлечение числа из стека

{ return st[top--]; }

};

//---------------------------------------------------------------------------

class Stack2 : public Stack {

public:

void push(int var) { // помещение числа в стек

if (top > MAX-1) cout << "\nError: stack polon!"; // если стек полон, то ошибка

Stack::push (var); // если всё в порядке, то вызов функции push класса Stack

}

int pop( ) { // извлечение числа из стека

if (top < 0) cout << "\nError: stack pust!\n"; // если стек пуст, то ошибка

return Stack::pop( ); // если всё в порядке, то вызов функции pop класса Stack

}

};

//---------------------------------------------------------------------------

int main( ) {

Stack2 s1;

s1.push(11); // поместим в стек несколько чисел

s1.push(22);

s1.push(33);

cout << endl << s1.pop( ); // заберем числа из стека

cout << endl << s1.pop( );

cout << endl << s1.pop( );

cout << endl << s1.pop( ); // !!!, а данных-то больше нет

return 0; }

Как видно из данного примера, в классе Stack2 содержатся два метода push() и pop(), которые имеют те же имена, аргументы и возвращаемые значения, что и методы базового класса. В связи с этим возникает вопрос: Как компилятор поймёт, какой из методов вызвать? Существует правило: если один и тот же метод существует и в базовом, и в производном классе, то будет выполнен метод производного класса. Это правило справедливо только для объектов производного класса и не справедливо для объектов базового класса, поскольку им ничего не известно о производном классе, поэтому они всегда пользуются методами базового класса.

В нашем примере, в связи с тем что s1 – это объект производного класса Stack2, будет выполнен метод push() класса Stack2. Если стек полон, то метод пошлёт сообщение об ошибке, если – нет, то посредством строки Stack::push (var); вызывается метод push() базового класса Stack.