Доступ к членам
Часто бывает так, что внутреннее представление типа класса изменяется в последующих версиях программы. Допустим, опрос пользователей нашего класса Screen
показал, что для его объектов всегда задается размер экрана 80 ´ 24. В таком случае было бы желательно заменить внутреннее представление экрана менее гибким, но более эффективным:
class Screen { public: // функции-члены private: // инициализация статических членов (см. 13.5) static const int _height = 24; static const int _width = 80; string _screen; string::size_type _cursor; |
};
Прежняя реализация функций-членов (то, как они манипулируют данными-членами класса) больше не годится, ее нужно переписать. Но это не означает, что должен измениться и интерфейс функций-членов (список формальных параметров и тип возвращаемого значения).
Если бы данные-члены класса Screen
были открыты и доступны любой функции внутри программы, как отразилось бы на пользователях изменение внутреннего представления этого класса?
·
все функции, которые напрямую обращались к данным-членам старого представления, перестали бы работать. Следовательно, пришлось бы отыскивать и изменять соответствующие части кода;
· так как интерфейс не изменился, то коды, манипулировавшие объектами класса Screen только через функции-члены, не пришлось бы модифицировать. Но поскольку сами функции-члены все же изменились, программу пришлось бы откомпилировать заново.
Сокрытие информации – это формальный механизм, предотвращающий прямой доступ к внутреннему представлению типа класса из функций программы. Ограничение доступа к членам задается с помощью секций тела класса, помеченных ключевыми словами public, private и protected – спецификаторами доступа. Члены, объявленные в секции public, называются открытыми, а объявленные в секциях private и protected
соответственно закрытыми или защищенными.
· открытый член
доступен из любого места программы. Класс, скрывающий информацию, оставляет открытыми только функции-члены, определяющие операции, с помощью которых внешняя программа может манипулировать его объектами;
· закрытый член
доступен только функциям-членам и друзьям
класса. Класс, который хочет скрыть информацию, объявляет свои данные-члены закрытыми;
· защищенный член
ведет себя как открытый по отношению к производному классу и как закрытый по отношению к остальной части программы. (В главе 2 мы видели пример использования защищенных членов в классе IntArray. Детально они рассматриваются в главе 17, где вводится понятие наследования.)
В следующем определении класса Screen
указаны секции public и private:
class Screen { public: void home() { _cursor = 0; } char get() { return _screen[_cursor]; } char get( int, int ); void move( int, int ); // ... private: string _screen; string::size_type _cursor; short _height, _width; |
Согласно принятому соглашению, сначала объявляются открытые члены класса. (Обсуждение того, почему в старых программах C++ сначала шли закрытые члены и почему этот стиль еще кое-где сохранился, см. в книге [LIPPMAN96a].) В теле класса может быть несколько секций public, protected и private. Каждая секция продолжается либо до метки следующей секции, либо до закрывающей фигурной скобки. Если спецификатор доступа не указан, то секция, непосредственно следующая за открывающей скобкой, по умолчанию считается private.