246071-Либерти-Освой-самостоятельно-С-за-21-день (852741), страница 24
Текст из файла (страница 24)
Чтобы получить доступ к переменным- членамклассаCat,откройтеихследующимспособом:classCat{public:unsignedintitsAge;unsignedintitsWeight;voidMeow();};Теперьблагодаряключевомусловуpublicвсечленыкласса(itsAge,itsWeightиMeow())сталиоткрытыми.Влистинге8.1показанообъявлениеклассаCatсоткрытымипеременными-членами.Листинг8.1.Доступкоткрытымчленампростогокласса1://Примеробъявлениеклассас2://открытымичленами3:4:#include<iostream.h>//дляиспользованияcout5:6:classCat//объявляемкласс7:{8:public://следующиечленыявляютсяоткрытыми9:intitsAge;10:intitsWeight;11:};12:13:14:intmain()15:{16:CatFrisky;17:Frisky.itsAge=5;//присваиваемзначениепеременной-члену18:cout<<"Friskyisаcatwhois";19:cout<<Frisky.itsAge<<"yearsold.\n";20:return0;21:}Результат:Friskyisаcatwhois5yearsold.Анализ:Встроке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()восновномкодепрограммы.Привызовевпрограммеметодадоступаненужнознать,хранитсялинужноезначениевпеременнойтипаunsignedintegerилиlongлибооновычисляетсяпризапросе.Такойподходоблегчаетэксплуатациювашейпрограммыиееподдержкувбудущем.Можносказать, что он продлевает жизнь программе, поскольку, изменяя классы, можно существенномодернизироватьвыполнениепрограммы,незатрагиваяприэтомосновногокода.В листинге 6.2 показан класс Cat, в котором в этот раз объявлены закрытые переменныечленыиоткрытыеметодыдоступакзакрытымданным.Обратитевнимание,чтопередваминевыполняемыйвариантпрограммы,атолькообъявлениекласса.Листинг6.2.Объявлениеметодовдоступакданнымкласса1://ОбъявлениеклассаCat2://Переменные-членыобъявляютсязакрытыми,аоткрытыеметодыдоступа3://обеспечиваютинициализациюпеременных-членовивозвращениеихзначений4:5:classCat6:{7:public:8://открытыеметодыдоступа9:unsignedintGetAge();10:voidSetAge(unsignedintAge);11:12:unsignedintGetWeight();13:voidSetWeight(unsignedintWeight);14:15://открытыефункции-члены16:voidMeow();17:18://закрытыепеременные-члены19:private:20:unsignedintitsAge;21:unsignedintitsWeight;22:23:};Анализ: Этот класс имеет пять открытых методов.
В строках 9 и 10 содержатся :/:<<**v>>>>* объявления методов обеспечения доступа к переменной-члену itsAge. А в строках12 и 13 объявляются методы доступа к переменной-члену itsWeight. Эти функции-членыинициализируютпеременныеивозвращаютихзначения.В строке 16 объявляется открытая функция-член Meow(). Функция Meow() не являетсяметодомдоступа.Онанеполучаетинеустанавливаетзначениепеременной-члена,авыполняетдругойвидсервисадлякласса,выводясловоMeowнаэкран.Самипеременные-членыобъявляютсявстроках20и21.Чтобы установить возраст кота Frisky, нужно передать соответствующее значение методуSetAge():CatFrisky;Frisky.SetAge(5);//устанавливаемвозрастFriskyспомощьюоткрытогометода-доступаОграничениедоступакданным-этонеспособзащитыданных,алишьсредствооблегченияпрограммированияОбъявление методов или данных закрытыми позволяет компилятору заблаговременнонаходитьошибкипрограммирования.Начинающиепрограммистычастоошибочнополагают,чтообъявляя данные закрытыми, тем самым скрывают некоторую секретную информацию отпользователей,неимеющихсоответствующихправдоступа.Вдействительностиэтонетак.Поэтому поводу Страустрап (Stroustrup), изобретатель языка C++, сказал: "Механизмы управлениядоступомвC++обеспечиваютзащитуотнесчастногослучая,нонеотмошенника"(ARM,1990).Рекомендуется:Объявляйтезакрытымипеременные-членыкласса(спомощьюключевогословаprivate).Объявляйте открытыми методы доступа к закрытым данным-членам класса.Используйтедляобработкиданных-членовзакрытыефункции-членыкласса.Нерекомендуется:Непытайтесьиспользоватьзакрытыепеременные-членывнекласса.КлючевоесловоclassКлючевоесловоclassимеетследующийсинтаксис:classимя_класса{//здесьнаходятсяключевыесловауправлениядоступом//здесьобъявляютьсяпеременныеиметодыкласса};Ключевое слово class используется для объявления новых типов.
Класс — это коллекцияданных-членов класса, которые представляют собой переменные различных типов, включаядругие классы. Класс также содержит функции класса, или методы, которые используются длявыполнениядействийнадданнымикласса,атакжедлявыполнениядругихвидовсервисавнутрикласса.Определение объектов нового типа во многом подобно определению любых переменных.Сначала указывается тип (класс), а затем имя переменной (объект). Для обращения к членамкласса Данным и функциям) используется оператор точки (.). Для объявления открытых илизакрытыхразделовклассаиспользуютсяключевыесловауправлениядоступомpublicилиprivate.По умолчанию действует закрытый режим доступа.
Каждое ключевое слово изменяет режимуправления доступом с момента использования этого ключевого слова и до конца объявленияклассаилидотехпор,поканевстретитсяследующееключевоесловоуправлениядоступом.Всеобъявленияклассовоканчиваютсязакрывающейфигурнойскобкойиточкойсзапятой.Пример1:classCat{public:unsignedintAge;unsignedintWeight;voidMeow();}CatFrisky;Frisky.Age=8;Frisky.Weight=18;Frisky.Meow();Пример2:classCar{public:voidStart();voidAccelerate();voidBrake();voidSetYear(intyear);intGetYear();private:intYear;CharModel[255];};CarOldFaithful;intbought;OldFaithful.SetYear(84);bought=OldFaithful.GetYear();OldFaithful.Start();ОпределениеметодовклассаКакупоминалосьвыше,методыдоступаобеспечиваютинтерфейсдляработысзакрытымипеременными-членамикласса.Дляметодовдоступа,какидлявсехдругихобъявленныхметодовкласса,следуетопределятьвыполнение.Такимобразом,методыобъявляютсяиопределяютсявклассе.Определение функции-члена начинается с имени класса, за которым следуют двадвоеточия,имяфункциииеепараметры.Влистинге6.3показанообъявлениепростогоклассаCat,вкоторомприсутствуютопределенияранееобъявленныхметодовдоступакданнымиоднойобычнойфункции-члена.Листинг6.3.определениеметодовпростогокласса1://Примеропределенияметодовв2://объявлениикласса3:4:#include<iostream.h>//дляобъектаcout5:6:classCat//началообъявлениякласса7:{8:public://началоразделаpublic9:intGetAgeO;//методдоступа10:voidSetAge(intage);//методдоступа11:voidMeow();//обычныйметод12:private://началораздела13:intitsAge;//переменная-член14:};15:16://GetAge,открытаяфункциядоступа,17://возвращаетзначениепеременной-членаitsAge18:intCat::GetAge()19:{20:returnitsAge;21:}22:23://ОпределениеоткрытойфункциидоступаSetAge24://ФункцияSetAge25://инициируетпеременную-членitsAge26:voidCat::SetAge(intage)27:{28://устанавливаемпеременную-членitsAgeравной29://значению,переданномуспомощьюпараметраage30:itsAge=age;31:}32:33://ОпределениеметодаMeow34://возвращаетvoid35://параметровнет36://используетсядлявыводанаэкрантекста"Meow"37:voidCat::Meow()38:{39:cout<<"Meow.\n";40:}41:42://Создаемвиртуальнуюкошку,устанавливаемеевозраст,разрешаем43://еймяукнуть,сообщаемеевозраст,затемснова"мяукаем".44:intmain()45:{46:CatFrisky;47:Frisky.SetAge(5);48:Frisky.Meow();49:cout<<"Friskyisаcatwhois";50:cout<<Frisky.QetAge()<<"yearsold.\n";51:Frisky.Meow();52:return0;53:}Результат:Meow.Friskyisаcatwhois5yearsold.Meow.Анализ:Встроках6—14содержитсяопределениеклассаCat.Строку8занимаетключевоесловоpublic,котороесообщаеткомпилятору,чтозанимследуетнабороткрытыхчленовкласса.Встроке9содержитсяобъявлениеоткрытогометодаGetAge(),которыйпредоставляетдоступкзакрытойпеременной-членуitsAge,объявляемойвстроке13.Встроке10объявляетсяоткрытаяфункция доступа SetAge(), которая принимает в качестве аргумента целочисленное значение иприсваиваетпеременнойitsAgeзначениеэтогоаргумента.В строке 11 объявляется метод Meow().
Этот метод не является функцией доступа кданным-членамкласса,аиспользуетсядлявыводанаэкрансловаMeow.В строке 12 начинается закрытый раздел, который включает только одно объявлениезакрытой переменной-члена itsAge (строка 13). Объявление класса завершается закрывающейфигурнойскобкойиточкойсзапятойвстроке14.Строки 18—21 содержат определение функции-члена GetAge(). Этот метод не принимаетникакихпараметровивозвращаетцелоезначение.Обратитевниманиенато,чтопри определении методов класса используется имя класса, за которым следуют двадвоеточия и имя функции (строка 18).