Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Лафоре Р. -> "Объектно-ориентированное программирование в С++" -> 140

Объектно-ориентированное программирование в С++ - Лафоре Р.

Лафоре Р. Объектно-ориентированное программирование в С++ — М.: Питер, 2004. — 992 c.
Скачать (прямая ссылка): obektnoorentprogramm2004.djvu
Предыдущая << 1 .. 134 135 136 137 138 139 < 140 > 141 142 143 144 145 146 .. 341 >> Следующая


причине переполнения массива st [ ]. А при попытке извлечения количества чисел, большего, чем находится в стеке, результат мог быть бессмысленным, так как начинали считываться данные, расположенные в памяти за пределами массива.

Для исправления этих дефектов мы создадим новый класс Stack2, производный от Stack. Объекты класса Stack2 ведут себя так же, как объекты класса Stack, за исключением того, что мы будем предупреждать о попытке переполнить стек или извлечь число из пустого стека. Вот листинг программы STAKEN:

// staken.срр

// перегрузка функций базового и производного классов #i ncl ude <iostream> using namespace std;

#include <process.h> // для exit ( ) /////////////////////////////////////////////////////////// class Stack

protected: // Замечание: использовать private нельзя
enum { МАХ = 3 ] [: // размер стека
int StC МАХ ]; // данные, хранящиеся в стеке
int top: // индекс последнего элемента в стеке
public:
Stack ( ): // конструктор
{ top = -1: }
void push ( int var ) // помещение числа в стек
{ stC ++top ] = var: }
int pop ( ) // извлечение числа из стека

{ return stC top-- ]: }

}:

///////////////////////////////////////////////////////////

class Stack2 : public Stack {

public:

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

if ( top >= MAX - 1 ) // если стек полон, то ошибка

{ cout « "ХпОшибка: стек полон": exit ( 1 ): } Stack::push ( var ): // вызов функции push класса Stack

}

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

{

if ( top < 0 ) // если стек пуст, то ошибка

{ cout « 'ЛпОшибка: стек пуст\п": exit Cl); } return Stack::pop ( ): // вызов функции pop класса Stack

}

} ;

///////////////////////////////////////////////////////////

int main ( ) {

Stacks si:

si.push ( 11 ) si.push ( 22 ) si.push ( 33 )

// поместим в стек несколько чисел

cout « endl « si.pop ( ); // заберем числа из стека 372 Глава 9. Наследование

cout « endl « si.pop ( ); cout « endl « si.pop ( ):

cout « endl « si.pop ( ): // ой. а данных-то больше нет cout « endl: return 0:

}

В этой программе класс Stack тот же, что и в программе STAKARAY, за исключением того, что данные класса объявлены как protected.

Какой из методов использовать?

В классе Stack2 содержатся два метода: push() и рор(). Эти методы имеют те же имена, агументы и возвращаемые значения, что и методы класса Stack. Если мы вызываем эти методы из функции main() оператором типа:

Si.push ( 11 ):

то как же компилятор поймет, какой из двух методов push() вызвать? Существует правило: если один и тот же метод существует и в базовом, и в производном классе, то будет выполнен метод производного класса. (Это верно для объектов производного класса. Объектам базового класса ничего не известно о производном классе, поэтому они всегда пользуются методами базового класса.) В этом случае мы говорим, что метод производного класса перегружает метод базового класса. Для нашего примера, так как Sl — это объект класса Stack2, то будет выполнен метод push() класса Stack2, а не класса Stack.

Метод push() класса Stack2 проверяет, полон ли стек: если да, то он посылает сообщение об ошибке и завершает программу; если нет, то вызывается метод push() класса Stack. Таким же образом метод рор() класса Stack2 осуществляет проверку того, пуст ли стек. Если да, то выводится сообщение об ошибке и программа завершается, если нет, то вызывается метод рор() класса Stack.

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

33 22 11

Ошибка-, стек пуст и программа завершается.

Операция разрешения и перегрузка функций

Как же методы push() и рор() класса Stack2 получают доступ к методам push() и рор() класса Stack? Они используют операцию разрешения :: следующим образом: Stack::push ( var ); и

return Stack::pop ( ): Наследование в классе Distance

373

В этих строках определено, что будут вызваны методы push() и рор() класса Stack. Без операции разрешения компилятор подумает, что методы push() и рор() класса Stack2 вызывают сами себя, что, в нашем случае, приведет к ошибке программы. Использование операции разрешения позволяет точно определить к какому классу относится вызываемый метод.

Наследование в классе Distance

Мы рассмотрим более сложный пример использования наследования. До сих пор в примерах этой книги, использующих класс Distance, предполагалось, что интервал может иметь только положительное значение. Обычно это используется в архитектуре. Однако, если мы будем измерять уровень Тихого океана с учетом его приливов и отливов, то нам может понадобиться отрицательное значение интервала. (Если уровень прилива меньше уровня моря, то он называется отрицательным приливом; он дает сборщикам моллюсков большее пространство обнаженного пляжа.)

Давайте создадим новый производный класс от класса Distance. В этот класс мы добавим поле для наших измерений, которое содержит знак: отрицательный или положительный. А также нам нужно будет изменить методы класса, чтобы они могли работать со знаковым значением интервала. Приведем листинг программы ENGLEN: // englen.cpp
Предыдущая << 1 .. 134 135 136 137 138 139 < 140 > 141 142 143 144 145 146 .. 341 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100