246071-Либерти-Освой-самостоятельно-С-за-21-день (852741), страница 23
Текст из файла (страница 23)
И чемближеэтипеременныесоответствуютреальности,темлегченаписатьтакуюпрограмму.КлассыичленыклассовНовыйтипсоздаетсяпутемобъявлениякласса.Класс—этопростоколлекцияпеременных(причемчасторазличныхтипов),скомбинированнаяснаборомсвязанныхфункций.Автомобильможнопредставлятьсебепо-разному,напримеркакколлекцию,состоящуюизколес, дверей, сидений, окон и т.д. Или же, думая об автомобиле, можно представить себе егоспособность двигаться, увеличивать скорость, тормозить, останавливаться, парковаться и т.д.Класспозволяетинкапсулироватьразличныезапчастиавтомобиляиегоразнообразныефункцииводнуколлекцию,котораяназываетсяобъектом.Инкапсуляциявсего,чтомызнаемобавтомобиле,водинклассимеетдляпрограммистарядпреимуществ.Ведьвсесведениясобранывместеводномобъекте,накоторыйлегкоссылаться,копировать и манипулировать его данными. Клиенты вашего класса, т.е.
части программы,работающиесэтимклассом,могутиспользоватьвашобъект,небеспокоясьотом,чтонаходитсявнемиликакименноонработает.Класс может состоять из любой комбинации типов переменных, а также типов другихклассов. Переменные в классе называют переменными-членами или данными- членами. КлассCarможетиметьпеременные-члены,представляющиесидения,радиоприемник,шиныт.д.Переменные-члены, известные также как данные-члены, принадлежат только своемуклассу.
Переменные-члены — это такие же составные части класса, как колеса и мотор —составныечастиавтомобиля.Функции в классе обычно выполняют действия над переменными-членами. Ониназываются функциями-членами или методами класса. В число методов класса Car могутвходить Start() и Break().
Класс Cat может иметь такие данные-члены, которые представляютвозраст и вес животного, а функциональная часть этого класса может быть представленаметодамиSleep(),Meow()иChaseMice().Функции-члены принадлежат своему классу, как и переменные-члены. Они оперируютпеременными-членамииопределяютфункциональныевозможностикласса.ОбъявлениеклассаДляобъявленияклассаиспользуйтеключевоесловоclass,закоторымследуетоткрывающаяфигурнаяскобка,азаней—списокданных-членовиметодовкласса.Объявлениезавершаетсязакрывающей фигурной скобкой и точкой с запятой. Вот, например, как выглядит объявлениеклассаCat:classCat{unsignedintitsAge;unsignedintitsWeight;voidMeow();};При объявлении класса Cat память не резервируется.
Это объявление просто сообщаеткомпиляторуосуществованииклассаCat,отом,какиеданныеонсодержит(itsAgeиitsWeight),атакже о том, что он умеет делать (метод Meow()). Кроме того, данное объявление сообщаеткомпилятору о размере класса Cat, т.е. сколько места должен зарезервировать компилятор длякаждогообъектаклассаCat.Посколькувданномпримередляцелогозначениятребуетсячетыребайта, то размер объекта Cat составит восемь байтов (четыре байта для переменной itsAge ичетыре—дляitsWeight).МетодMeow()нетребуетвыделенияпамятивобъекте.НесколькословобиспользуемыхименахНа программиста возложена ответственность за присвоение имен переменным- членам,функциям-членамиклассам.Какупоминалосьназанятии3,всегдаследуетдаватьпонятныеиосмысленныеимена.Например,Cat(Кот),Rectangle(Прямоугольник)иEmployee(Служащий)—вполне подходящие имена для классов, а Meow() (Мяу), ChaseMice() (ДогониМышку) иStopEngine()(ОстановкаДвигателя)—прекрасныеименадляметодов,посколькуизихназванийпонятно, что они делают.
Многие программисты сопровождают имена своих переменныхчленов префиксами its (например, itsAge, itsWeight, itsSpeed). Это помогает отличитьпеременные-членыотпеременных,неявляющихсячленамикласса.В языке C++ имеет значение регистр букв, и все имена классов должны следовать одномуобразцу. Исходя из этого, вам никогда не придется вспоминать, как именно пишется названиевашегокласса:Rectangle,rectangleилиRECTANGLE.Некоторыепрограммистылюбятдобавлятькименикаждогоклассаоднобуквенныйпрефиксс(отсловаclass)например,cCatилиcPerson,втовремякакдругиеиспользуютдляименитолькопрописныеилижетолькострочныебуквы.Япредпочитаюначинатьименаклассовспрописнойбуквы,напримерCatилиPerson.Такжемногиепрограммистыначинаютименафункцийспрописныхбукв,адляименвсехостальных переменных используют только строчные буквы. Слова, являющиеся составнымичастямиимен,разделяютобычносимволамиподчеркивания(например,Chase_Mice)илипростоначинаюткаждоесловоспрописнойбуквы(например,ChaseMiceилиDrawCircle).Важно придерживаться одного стиля на протяжении всей программы.
По мереприобретенияопытапрограммированиявашсобственныйстильнаписанияпрограммвключитвсебя соглашения не только по присвоению имен, но также и по отступам, выравниваниюфигурныхскобокиоформлениюкомментариев.Примечание:Обычно солидные компании по разработке программных продуктов имеютспециальные отделы, которые занимаются вопросами стандартизации, охватывающими истилевые особенности программ. Это гарантирует, что все разработчики смогут легкочитатьпрограммы,созданныеихколлегами.ОпределениеобъектаОбъект нового типа определяется таким же способом, как и любая целочисленнаяпеременная:unsigned int GrossWeight; // определяем беззнаковое целое Cat Frisky; // определяем объектCatВ этих программных строках определяется переменная с именем GrossWeight, котораяимеет тип unsigned int, а также определяется объект Frisky, который является объектом класса(илиимееттип)Cat.КлассывсравнениисобъектамиВамникогданепридетвголовупоигратьскошкойкаксабстрактнымпонятием,скореевыприласкаете свою настоящую мурку.
Не нужно много говорить о том, какая разницу междукошкойвообщеиконкретнымкотом,откоторогошерстьповсейкомнатеицарапинынаножкахстульев.ТочнотакаяжеразницамеждуклассомCat,представляющимсобойнекуюабстракцию,и отдельным объектом класса Cat. Следовательно, Frisky — это объект типа Cat в том самомсмысле,вкоторомGrossWeight—переменнаятипаunsignedint.Итак,мыпришликтому,чтообъект—этоотдельныйэкземплярнекоторогокласса.ПолучениедоступакчленамклассаПослеопределенияреальногообъектаклассаCat,напримерFrisky,унасможетвозникнутьнеобходимость в получении доступа к членам этого объекта.
Для этого используется операторпрямого доступа (.). Следовательно, чтобы присвоить число 50 переменной-члену WeightобъектаFrisky,можнозаписатьFrisky.Weight=50;Аналогично,длявызоваметодаMeow()достаточноиспользоватьследующуюзапись:Frisky.Meow();Когда нужно использовать некоторый метод класса, выполняется вызов этого метода. ВданномпримеревызываетсяметодMeow()объектаFrisky.Значенияприсваиваютсяобъектам,анеклассамВ языке C++ нельзя присваивать значения типам данных, они присваиваются толькопеременным.Например,такаязаписьневерна:int=5;//неверноКомпиляторрасценитэтокакошибку,посколькунельзяприсваиватьчислотипуint.Вместоэтого нужно определить целочисленную переменную и присвоить число 5 этой переменной.Например:intx;//определяемxкакпеременнуютипаintx=5://присвоениепеременнойxзначения5Таким образом, число 5 присваивается переменной x, которая имеет тип int.
Из тех жесоображенийнедопустимаследующаязапись:Cat.itsAge=5;//неверно???ЕслиCat—этокласс,анеобъект,токомпиляторотметитэтовыражениекакошибочное,поскольку нельзя присвоить число 5 переменной itsAge класса (т.е. типа) Cat. Вместо этогонужно определить объект класса Cat и присвоить число 5 соответствующей переменной-членуэтогообъекта.Например:CatFrisky;//этоопределениеаналогичноintx;Frisky.itsAge=5;//этоприсвоениеаналогичноx=5;Чтообъявишь,тоибудешьиметьПредставьтесебе,чтовыгуляетесосвоимтрехлетнимребенком,показываетеемукошкуиговорите: "Это Фриски, чудесная кошка, ну-ка Фриски, залай". Даже маленький ребенокрассмеетсяискажет:"Нет,кошкинеумеютлаять".Есливызапишете:CatFrisky;//создаемкошку(объект)noимениFriskyFrisky.Bark();//велимFriskyзалаятьтокомпилятортожесообщитвам,чтодажевиртуальныекошкилаятьнеумеют,посколькудля них не объявлен такой метод. В классе Cat есть метод Meow() (мяукать).
Если же вы неопределитевклассеCatметодMeow(),токомпиляторнепозволитвашейкошкедажемяукать.Рекомендуется:Используйте ключевое слово class для объявления класса. Используйтеоператорпрямогодоступа(.)дляполучениядоступакпеременным-членамиметодамкласса.Не рекомендуется:Не путайте объявление с определением. Объявление заявляет осуществовании класса, а определение резервирует память для объекта. Не путайте класс собъектом. Не присваивайте значения классу.
Присваивайте значения переменным-членамобъекта.ОграничениедоступакчленамклассаВ объявлении класса используются и другие ключевые слова. Двумя самыми важными изнихявляютсяpublic(открытый)иprivate(закрытый),определяющиедоступкчленамкласса.Всечленыкласса—данныеиметоды—являютсязакрытымипоумолчанию.Кзакрытымчленам можно получить доступ только с помощью методов самого класса. Открытые членыдоступныдлявсехдругихфункцийпрограммы.Определениедоступак членам класса имеет очень важное значение, и именно при решении этой задачиначинающие программисты часто сталкиваются с трудностями.
Чтобы прояснить ситуацию,рассмотримпример,которыйужеприводилсявышевэтойглаве:classCat{unsignedintitsAge;unsignedintitsWeight;voidMeow();};В этом объявлении переменные itsAge и itsWeight, а также метод Meow() являютсязакрытыми, поскольку все члены класса закрытые по умолчанию. Если требуется изменитьдоступкчленамкласса,тоэтоследуетсделатьявно.ЕсливпрограммебудетописанклассCat,какпоказановыше,тообращениекпеременнойчленуitsAgeизфункцииmain()вызоветошибкукомпиляции:CatBoots;Boots.itsAge=5;//Ошибка!НельзяобращатьсякзакрытымданнымИ в самом деле, сначала компилятору указывается, что члены itsAge, itsWeight и Meow()можно использовать только внутри класса Cat, а затем делается попытка использовать вовнешнейфункциипеременную-членitsAge,безраздельнопринадлежащуюобъектуBootsклассаCat.
Хотя объект Boots реально существует в программе, это не означает, что можно получатьдоступкчленамданногообъекта,закрытымдляпостороннегоглаза.Именно эти моменты с определением доступа к членам класса служат источникомбесконечных недоразумений у начинающих программистов. Я прямо-таки слышу вашудивленныйвопрос:"ЕсливпрограммеобъявленреальныйобъектBootsклассаCat,почемуженельзя присвоить значение переменной-члену этого объекта, даже обратившись к ней спомощьюоператорапрямогодоступа?"ДеловТом,чтовобъявленииклассаCatничегонеговоритсяовашихправахобращатьсякчленам этого класса, а это значит, что вы таких прав не имеете. Только собственные методыобъектаBootsвсегдаимеютдоступковсемданнымкласса,какоткрытым,такизакрытым.Даженесмотрянато,чтовысамисоздаликлассCat,этонедаетвамправавозвращатьилиизменятьвпрограммеегоданные,которыеявляютсязакрытыми.Однако из любого положения есть выход.