С++ для начинающих




Объектно-ориентированный подход - часть 3


}

// ниже идут обращения к функции swap:

IntArray ia;

IntArrayRC iarc;

IntSortedArray ias;

// правильно - ia имеет тип IntArray

swap (ia,0,10);

// правильно - iarc является подклассом IntArray

swap (iarc,0,10);

// правильно - ias является подклассом IntArray

swap (ias,0,10);

// ошибка - string не является подклассом IntArray

string str("Это не IntArray!");

swap (str,0,10);

Каждый из трех классов реализует операцию взятия индекса по-своему. Поэтому важно, чтобы внутри функции swap() вызывалась нужная операция взятия индекса. Так, если swap() вызвана для IntArrayRC:

swap (iarc,0,10);

то должна вызываться функция взятия индекса для объекта класса IntArrayRC, а для

swap (ias,0,10);

функция взятия индекса IntSortedArray. Именно это и обеспечивает механизм

виртуальных функций С++.

Давайте попробуем сделать наш класс IntArray базовым для иерархии подклассов. Что нужно изменить в его описании? Синтаксически – совсем немного. Возможно, придется открыть для производных классов доступ к скрытым членам класса. Кроме того, те функции, которые мы собираемся сделать виртуальными, необходимо явно пометить специальным ключевым словом virtual. Основная же трудность состоит в таком изменении реализации базового класса, которая позволит ей лучше отвечать своей новой цели – служить базой для целого семейства подклассов.

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

(public) и закрытого (private).

Если используется наследование, то к этим двум группам разработчиков добавляется третья, промежуточная. Производный класс может проектировать совсем не тот человек, который проектировал базовый, и для того чтобы реализовать класс-наследник, совсем не обязательно иметь доступ к реализации базового. И хотя такой доступ может потребоваться при проектировании подкласса, от конечного пользователя обоих классов эта часть по-прежнему должна быть закрыта. К двум уровням доступа добавляется третий, в некотором смысле промежуточный, – защищенный (protected). Члены класса, объявленные как защищенные, могут использоваться классами-потомками, но никем больше. (Закрытые члены класса недоступны даже для его потомков.)




Содержание  Назад  Вперед