Г. Шилдт - Полный справочник по C++ (1109478), страница 48
Текст из файла (страница 48)
Все псрсмсшгыс или функции, размсщсгпгыс в развело рл)г11о„лос)упиы лля любых фупкций программь). По существу. вис)шгяя часть ггрограммы получает доступ к объекту имсиио через его открытыс функции-члсиы. Хотя псрсмсцпыс можно объявлять открытыми, этого слслуст избегать Наоборот, все ла) шыс рскомспдустся объявлять закрытыми, коитролируя поступ к пим с помо)цью открьпъгх функций.
Кроме того, обратите внимание иа то, что восле кл)о*)свого слова роЬ11с в опрсдслсиии класса ввао)с стоит ЛвОетОЧИс. Функции ьпьсО, ровЫ) и рор() иазыва)отса фуггкгггглми-иле)сами, поскольку опи являются частью класса всао)с. Псрсмсипыс все)с и сов пазываюзся переменными- членами (илп с)лггнъгмгг- ыенаьчг). Напомним. объект созласт связь мсжлу кодом и данными. Только фупкции-члспы имскп поступ к закрьпым членам своего класса. Следовательно, доступ к псрсмсщ)ым все)с и сов имеют')олько фупкции зззЫ(), равЬО и рорО. Определив класс, можно созлать объект этого типа. В сущности, имя класса становится повым спсцификатором типа лаыиых.
Например, слслуюший оператор создает объект с имспсм тувгас)с типа всаох. )( всасв тувсас)сг Объявляя объскт класса, вы созластс экземпляр ()пыапсс) этого класса. В даииом случае псрсмсииая вувсас)с является экземпляром класса всас)с. Кроме того, объекты можио созлавать, указывая их имя сразу после опрслслсиия класса, т.е. после закрывающей фигурпой скобки (го'пю так жс, как экземпляр структуры). В языке С-ь-ь с помощью ключевого слова с1авв опрслслястся новый тип данных, который можпо использовать лля создания объектов этого типа, Слсловатсльно, объект — это экземпляр класса. В этом смыслс оц )гичсм пс отличается от лругих перемсииых, папримср, от псрсмсшюй, прслставляюшсй собой экземпляр типа 1пс.
Иначе говоря, класс является лши гсской абстракцией, а объект — ес реальным воплоше)гисм, существующим в памяти компьютера. Опрслслсцис простого класса имеет слслуюпши вид. с1авв иик кгасса злкрытые ггеременные и функчии рос)ьс: откръит ге переменные и фгзнкигггг слкслк ивен объектов; Естсствсиио, список гглген объектов может быть пустым. Внутри ог)рслслс)шя класса в(:ас)с функции- )лспы идентифицируются с помощью своих прототипов.
Напомиим, что в языке С.ь+ все фупкции должны иметь прототипы. Таким образом, прототипы являются псотьсмлсмой частью класса. Прототип фуикции-члспа. размсшспцыи впугри опрслслсиия класса, имеет тот жс смысл, что и про~огни обычпои г)гупкции. Часть й. Язык С++ Кодируя функцию-член класса, нсобхолимо сообщить компьютеру, какому именно классу она принадлежит. Для этого перед сс именем следует указать имя соответствующего класса. Вот как, например, определяется функция рив)хО из ювюса всас)с. го' д всасй.: рнсд ( кос 1Х(сов==я?ЕЕ) ( соне « *'С' ек переполнен.тп"; геьпхп,- ) всех(сов) .— (г сов++; ) Оператор "::" назывсстсл оператором разрешения области видимости (хсоре гезоЬ- акоп орега(ог).
Оп сообщает компилятору, по данная версия функции рпв)х() принадлежит классу вевс)с, т.с. функция рпв)э() пребывает в области видимости класса вевс)х. Благодаря оператору разрешения области видимости компилятор всегла знает. какому классу принадлежит каждая из функция. Ссылаясь на член класса извне. всегда следует указывать конкретный объект, которому этот член при1)одлсжит. Для этого используется имя объекта, за которым следует оператор "." и имя члена. Зто правило относится как к данным-членам, так и к функциям- членам. Вот как, например, вызывается функция хпХе () . принадлежащая объекту зевс)х1.
| веасх веасЫ., веасх2; всасхх.(пус(); В этом фрагменте создаются два объекта — вевс)хх и всвс(х2, а затем объект вевс)а. инициализируется с помощью функции хпхе О. Обратите внимание на то, что переменные всвсИ. и всвс)е2 представляют собой лва разных объекта. ['аким образом, инициализация объеьла вевс)<ъ не означаели инициализации обьскга веасв2. Объекты вевс)<ъ и вевс)г2 связьииет лишь то, что они являются экземплярами од) )ого и того жс класса Внутри класса функции-члены могут вызывать друг лруга и обращаться в переменным-членам.
пе используя оператор ".". Зтот оператор необходим, лишь когда обращение в функциям и персмс~шым-членам осуществляется извне класса. Рассхютрим завершенную программу, в которои опрслелястся класс аеас)е. М(пс1пс(е <Ьовсгеав> нв(пд павеврасе вес(; здехзпе ЭХЕЕ 100 l/ Определение класса аеас<. с1авв всаск Ъпе весх(отто); кпс сов; раас: чоЫ зпхе(); чоуб рнвл(ьпе (); епс рор(); ): чоь<( веасх:."~п(С О сов = 0; ) Глава 11. Обзор языка С++ уоЫ ясасК::рпв)т(1пс 1) 1Г(Сов'==агап! ( сопя .с "стек полон.гп"; ) яссу (соя) соя~+; (пс ясасй::рор() ( гб(Соя=.-О) ( соне « "стек пуст. 1п"; геьевп 6; ) соя--; гесшт~ вссК[ьов); ! гпс мата() ясасК втасК1, веасК2; // Создаем лва объекта класса ясасй ясасК1.1пъс()," яеасК2.1пъс(); всасК1.риац(1) всасК2.рпяй(2) яеасК1.рпя)т(3); ясасК2.рпв)т(4); сопс « всасК1.рор() « соне « веасК1.рор() сс попс « ясасК2.рор() сс попс « всасК2.рор() « " (п"! сесатп О; ) Резульщт работы этой программы показан ниже.
$1 1 а Не забывайтс: закрытые члены объекта лоступпы ~олько функциям-членам, прииаллежащим этому же обьекту. Например, в предыдущем примере оператор я всасК1.сов = О; // ошибка, переменная Еоя является закрытой. нельзя было бы поместить в функцию иазл(), поскольку переменная сов является закрытым членом объекта всасК1. 1:3 Перегрузка функций Перегрузка Функций является одной из разновидностей полиморфизма.
В языке С++ допускается использование функций с олипаковыми именами, но разными объявлениями параметров, В таких случаях говорят, что функции лерегрулгены, а сам процесс называется перегрузкой фуикцгтй. Часть ((. Язык С++ Чтобы понять, наскольк() никем механизм перегрузки, рассмотрим три Функции, опрелеленные в полмножествс С: аьв(), 1аьв() и ааьв(). гРункция аьв() возвращает абсолютное значение целого числа, Функция 1аьв() вычисляет абсолютное значение переменной типа 1опд 1пе, а Функция яаьв() предназначена для определения абсолютного значения переменной типа доеьзе. несмотря на то по зги Функции выполняют практически идентичные операции, в языке С для них предусмотрено трн разных, хотя и мало отличающихся, имени.
Это слишком усложняет ситуацию, программист должен постоянно помнить, какую Функцию следует вызывать в том или ином случае. Однако в языке С++ все три Функции можно назвать одинаково. Рассмотрим пример. «1пс1цс)е <1овсгеаи> цв1пд памеврасе вес," // Функция аЬв перегружена трижды. (пе аЬв(1пс 1); г)оиь1е аЬв Иоиь1е д); 1опд аЬв(1опд 1); 1пс па1п() ( соне «аЬв (-10) « "1п"; соис « аЬв(-11.0) « "1п"; соне « аЬв(-91) « " (п"; геецгп 0; 1пе аЬв(ьпс 1) ( соцс « "Функция аЬв() с аргументом типа 1пе(п'; геспгп 1<0 ? -1 : 1; ) цоць1е аьв [с)оць1е 0] ( сонЕ « "Функция аЬв() с аргументом тю1а г)оць1еМ"? геецгп о<0.0 ? -с): 0," 1опд аЬв(1опд 1) ( соне « "Функция аЬв() с аргументом типа 1опд(п"; гесцгп 1<0 ? -1 : 1; Эта программа вычисляет следующие результаты. Функция аЬв с аргументом типа 1це." 10 Функция аЬв с аргументом типа цоць1е: 11 Функция аЬв с аргументом типа 1опд: 9 гл Глава 11.
Обзор языка С++ В этой программе опрелелены три похожие, но разные функции с именем а)зв(), каждая из которых возвращает абсолютное значение сносго аргумента. В каждом конкретном случае компилятор автоматически выбирает полходяшую функцию, ос)ювываясь на информации о типе аргумента. Ценность механизма перегрузки заключается в том, что он позволяет обращаться к функциям, близким по смыслу, используя олно и то же имя. Таким образом, имя вня() является назва)(исм общей олерации, а компилятор сам должен выбрать ее конкре/аную реализацию в зависимости от контекста. Нужно лишь помнить, какая общая операция должна быть выполнена.
Итак, благодаря полиморфизму три сушности были заменены одной. Разумеется, этот пример слишком тривиален, но, развивая эту концепцию, можно применить полиморфизм для управления работой более сложных программ. Как правило, чтобы перегрузить какую-то функцию, достаточно определить три ее разные версии, а компилятор сам позаботится об остальном.
Олнако следует помнить об одном важном ограничении: тип и/или количестно параметров каждой перегруженной функции должны быть разными. Нельзя перегрузить функции, отличаюгдиеся лишь типом возврашаемого значения. Этого совершенно нсдосппо шо. поскольку необхолимо, чтобы типы и/или количестно параметров н каждан версии отличались друг от лруга. (Информации о типе возврашаемого значения нслостаточно для того. чтобы компилятор правильно распознал нужный вариант перегруженной функции.) Разумеется„это нс значит, что персгружасмыс функции должны имсть одинаковый тип возврашаемого значения. Просто для перегрузки этого мачо.
Рассмотрим сше олин пример перегруженных функций. Фьпс1цде <1сястеат> Вупс1цг)е <снег))о> Мхос1цае <свххтпд> цяхпй пягаеярасе яес); чсьс яхтааг)(с)зат *я1, спат 'в2) чей вехаг)<((спят "в1, упе з); ьпс еа1п() ( сйат яст(80) вххсру(ясх, "Всем "); вхтасс(вхт, "привет"); сост « ясх « " тп"; вегас)г)(яхт, 100); ссцс « яст « "тп"; техцтп 0; // Конкатенация двух строк чоьд ветвей(снах *в1, с)1ат "в2) ( яттсвс(я1, я2]; ) // Конкатенация строки и целого числа, преобразованного в строку чоЫ вххаг)г)(с)зах *в1, ьпе 1) с)1ат сеер(80); вртупей(гетр, "Ъд', 1); яетсас(в1, Сепр)) ) Часть П. Язык С++ В этой программе фуцкция векадд() является перегруженной.