Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Ограничение доступа к членам класса
В объявлении класса используются и другие ключевые слова. Двумя самыми важными из них являются public (открытый) и private (закрытый), определяющие доступ к членам класса. Все члены класса — данные и методы — являются закрытыми по умолчанию. К закрытым членам можно получить доступ только с помощью методов самого класса. Открытые члены доступны для всех других функций программы. Определение доступа к членам класса имеет очень важное значение, и именно при решении этой задачи начинающие программисты часто сталкиваются с трудностями. Чтобы прояснить ситуацию, рассмотрим пример, который уже приводился выше в этой главе:
class Cat { unsigned int itsAge; unsigned int itsWeight; void Meow(); };
В этом объявлении переменные itsAge и itsWeight, а также метод Meow() являются закрытыми, поскольку все члены класса закрытые по умолчанию. Если требуется изменить доступ к членам класса, то это следует сделать явно. Если в программе будет описан класс Cat, как показано выше, то обращение к переменной-члену itsAge из функции main() вызовет ошибку компиляции:
Cat Boots; Boots.itsAge = 5; // Ошибка! Нельзя обращаться к закрытым данным
И в самом деле, сначала компилятору указывается, что члены itsAge, itsWeight и Meow() можно использовать только внутри класса Cat, а затем делается попытка использовать во внешней функции переменную-член itsAge, безраздельно принадлежащую объекту Boots класса Cat. Хотя объект Boots реально существует в программе, это не означает, что можно получать доступ к членам данного объекта, закрытым для постороннего глаза. Именно эти моменты с определением доступа к членам класса служат источником бесконечных недоразумений у начинающих программистов. Я прямо-таки слышу ваш удивленный вопрос: " Если в программе объявлен реальный объект Boots класса Cat, почему же нельзя присвоить значение переменной-члену этого объекта, даже обратившись к ней с помощью оператора прямого доступа? " Дело в Том, что в объявлении класса Cat ничего не говорится о ваших правах обращаться к членам этого класса, а это значит, что вы таких прав не имеете. Только собственные методы объекта Boots всегда имеют доступ ко всем данным класса, как открытым, так и закрытым. Даже несмотря на то, что вы сами создали класс Cat, это не дает вам права возвращать или изменять в программе его данные, которые являются закрытыми. Однако из любого положения есть выход. Чтобы получить доступ к переменным- членам класса Cat, откройте их следующим способом:
class Cat { public: unsigned int itsAge; unsigned int itsWeight; void Meow(); };
Теперь благодаря ключевому слову public все члены класса (itsAge, itsWeight и Meow()) стали открытыми. В листинге 8.1 показано объявление класса Cat с открытыми переменными-членами. Листинг 8.1. Доступ к открытым членам простого класса 1: // Пример объявление класса с 2: // открытыми членами 3: 4: #include < iostream.h> // для использования cout 5: 6: class Cat // объявляем класс 7: { 8: public: // следующие члены являются открытыми 9: int itsAge; 10: int itsWeight; 11: }; 12: 13: 14: int main() 15: { 16: Cat Frisky; 17: Frisky.itsAge =5; // присваиваем значение переменной-члену 18: cout < < " Frisky is а cat who is "; 19: cout < < Frisky.itsAge < < " years old.\n"; 20: return 0; 21: }
Результат: Frisky is а cat who is 5 years old.
Анализ: В строке 6 содержится ключевое слово class. Оно сообщает компилятору о том, что следующий после него блок является объявлением класса. Имя нового класса стоит сразу после ключевого слова class. В данном случае у нас объявляется класс Cat. Тело объявления класса начинается с открывающей фигурной скобки в строке 7 и заканчивается закрывающей фигурной скобкой и точкой с запятой в строке 11. Строка 8 содержит ключевое слово public, которое означает, что до тех пор, пока не встретится ключевое слово private или конец объявления класса, все последующие члены объявляются открытыми. В строках 9 и 10 объявляются переменные-члены itsAge и itsWeight. В строке 14 начинается функция main() программы. Frisky определяется в строке 16 как экземпляр класса Cat, т.е. как объект класса Cat. В строке 17 возраст объекта Frisky (значение переменной itsAge) устанавливается равным 5. А в строках 18 и 19 переменная-член itsAge используется для вывода данных на экран.
Примечание: Попробуйте заблокировать символом комментария строку 8 и перекомпилировать программу. Компилятор покажет сообщение об ошибке в строке 17, поскольку к переменной itsAge больше нет открытого доступа, ведь по умолчанию все члены класса объявляются как закрытые. Оставьте данные класса закрытыми
Согласно общей стратегии использования классов переменные-члены класса следует оставлять закрытыми. Благодаря этому достигается инкапсуляция данных внутри класса. Доступ следует открывать только к функциям-членам класса, обеспечивающим доступ к его закрытым данным (эти функции еще называют методами доступа). Эти методы можно вызывать из любого места в программе для возвращения или установки значений закрытых переменных-членов. Зачем же используются в программе такие посредники между закрытыми членами класса и остальной программой? Не проще ли открыть данные класса для внешнего доступа, вместо того чтобы работать с методами доступа? Дело в том, что применение методов доступа позволяет скрыть от пользователя детали хранения данных в объектах, в то же время, снабжая их методами использования этих данных. В результате можно модернизировать способы хранения и обработки данных внутри класса, не переписывая при этом методы доступа и вызовы их во внешнем программном коде. Если для некоторой внешней функции в программе, возвращающей возраст объекта Cat, открыть непосредственный доступ к переменной itsAge, то эту функцию пришлось бы переписывать в том случае, если автор класса Cat решит изменить способ хранения этого компонента данных. Однако если между внешней функцией и данными класса будет стоять функция-член GetAge(), то класс Cat можно будет модернизировать сколько угодно раз, что никак не повлияет на способ вызова функции GetAge() в основном коде программы. При вызове в программе метода доступа не нужно знать, хранится ли нужное значение в переменной типа unsigned integer или long либо оно вычисляется при запросе. Такой подход облегчает эксплуатацию вашей программы и ее поддержку в будущем. Можно сказать, что он продлевает жизнь программе, поскольку, изменяя классы, можно существенно модернизировать выполнение программы, не затрагивая при этом основного кода. В листинге 6.2 показан класс Cat, в котором в этот раз объявлены закрытые переменные-члены и открытые методы доступа к закрытым данным. Обратите внимание, что перед вами не выполняемый вариант программы, а только объявление класса. Листинг 6.2. Объявление методов доступа к данным класса 1: // Объявление класса Cat 2: // Переменные-члены объявляются закрытыми, а открытые методы доступа 3: // обеспечивают инициализацию переменных-членов и возвращение их значений 4: 5: class Cat 6: { 7: public: 8: // открытые методы доступа 9: unsigned int GetAge(); 10: void SetAge(unsigned int Age); 11: 12: unsigned int GetWeight(); 13: void SetWeight(unsigned int Weight); 14: 15: // открытые функции-члены 16: void Meow(); 17: 18: // закрытые переменные-члены 19: private: 20: unsigned int itsAge; 21: unsigned int itsWeight; 22: 23: };
Анализ: Этот класс имеет пять открытых методов. В строках 9 и 10 содержатся: /: < < **v> > > > * объявления методов обеспечения доступа к переменной-члену itsAge. А в строках 12 и 13 объявляются методы доступа к переменной-члену itsWeight. Эти функции-члены инициализируют переменные и возвращают их значения. В строке 16 объявляется открытая функция-член Meow(). Функция Meow() не является методом доступа. Она не получает и не устанавливает значение переменной-члена, а выполняет другой вид сервиса для класса, выводя слово Meow на экран. Сами переменные-члены объявляются в строках 20 и 21. Чтобы установить возраст кота Frisky, нужно передать соответствующее значение методу SetAge(): Cat Frisky; Frisky.SetAge(5); // устанавливаем возраст Frisky с помощью открытого метода-доступа
Популярное:
|
Последнее изменение этой страницы: 2017-03-08; Просмотров: 490; Нарушение авторского права страницы