Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 61
Текст из файла (страница 61)
Другими словами, ти!аЫе означает: «ни прн каких условиях не является сопИт Этим можно воспользоваться для упрощения определения в!ппи гер (): в!г!пд!ла!е в!г!пи гер ((сопв1 ( !/ (Мас1!е иаЩ ( сотри!е сае1!е иа1ие((, савве иа!16 = тие; ге!игп сасле; В результате, использование в!ппсг гер (( становится корректным. Например: 11п!е дЗ, солИтза1е дв'; вггспдвЗ= дЗ.в!пни гер ((, в!г!пива = 64 в1г!пи гер ((; О правильно! Объявление имен г квалификатором ти1аЫе наиболее приемлемо, когда (только лишь) часть представления может быть модифицирована, Если больцзая часть объекта подвержена изменениям, в то время как с логической точки зрения объект остается константой, часто предпочтительнее поместить изменяющиеся данные в отдельный объект Глава 1О.
Классы 280 и осуществлять доступ к нему косвенно. С использованием такой техники пример кэширования строки принимает следующий впд: в1 исссасде( Ьоо! оа1!д, в!лад гер; с1авв Ваге ( сасде* с; >>/ннаинвлизируется в конаирукпюре (З !д 4 б) иоЫ сотри1е савйе оа!ие () сопя!; о риЬ1!с: 0- вгг1пцв1г!пд гер () сопв1; Д строковое представление в1ппдВагесв!ппу гер () сопя1 (1' (~с->вайд) ( сотри1е сасае иаые (); с — >оайс1 = 1гие, ге!игл с->гер; Техника программирования с использованием кзш-памятн обобщается до различ- ных форм минимизации вычислений.
10.2.8. Структуры и классы По определению структура есть класс, все члены которого по умолчанию являются открытыми, то есть в!гас! в ( является просто более короткой формой записи с1авв в ( риЫЫ. Модификатор доступа рг!тэа!е: можно использовать для указания того, что последующие члены являются закрытыми, аналогично тому, как риЫ!с: указывает на то, что пес.лсдуюшие члены открыты. За исключением раз.личий в именах следующие объявления эквивалентны: с1авв Ва1е1 ( !и! с(, т, у, риЫ!с.
Ва1е1 (Ы1 с(д, и>1 т т, !п1 уу), ооЫасЫ уеаг(!пгп), !!прибавить влет в1 гос1 Ва1е2 ( ргсоа1е: 281 10.2. Классы 1п1 <1, т, у; рибйс Ва<е2 (1п1 <И, <л1тт, 1л<ууг оо1<1а<1<1 уеаг~1л<п) 1<< прибавить ивет )' Какого стиля придерживаться, зависит от обстоятельств и вкуса. Я обычно предпочитаю использовать структуры для классов, у которых все данные открыты. Я думаю о таких классах, како «не совсем типах, являющихся просто структурамп данныхе«Конструкторы и функции доступа могут быть весьма полезны даже лля таких структур, но скорее для удобства, а не как гаранты свойств типа (инварнантов, см.
9 24.3.7.1). Объявление данных в начале класса не является требованием. В действительности, имеет смысл помещать данные в конце, чтобы сдела~ь акцент на функциях открытого интерфейса. Например: с1авв ВагеЗ ( рибйс. Ва1еЗ (1л< <Ы, <л<тт, <л1 УМ <<<< прибавить влет оо1<(а<1<1 уеаг(1л1л) рг1ои<е: ш1<1, т, у; В реальном коде, где и открыл ый интерфейс, и детали реализации обычно более объемны, чем в учебных примерах, я обычно предпочитаю стиль, испол ьзованньш в Ва1еЗ. Модификаторы доступа можно и<пользовать несколько раз в одном и том же объявлении класса. Например: с1ивв Ва<е4 ( риЫ<с Ва1е4 <<л1 <1<1, ш1 тт, ш1уу) рпоа<е: и<1 <1, т, у; риЫ2 ооИ а<И уеаг ~<и< п~< ), 1' прибавить ° лет Введение нескольких открытых разделов (как в Ва1е4) часто запутывает программиста.
То же самое можно сказать и о нескольких закрытых разделах. Однако разрешение множества модификаторов доступа в классе полезно при автоматической генерации кода. 10.2.9. Определение Функции в классе Функция, определенная в пределах определения класса (а не просто там объявленная), является встроенной функцией-членом. То есть, определение функций-членов в классе предназначено для небольших по размеру и часто используемых функций. Так же, как и определение класса, частью которого она является, определение в теле класса функции-члена может повторяться в нескольких единицах трансляции (в результате использования №1лс1и<(е).
Как и в случае с классом, ее смысл должен быть одинаков везде, где она используется 8 9.2.3), Глава 10. Классы Помещение определений членов данных в конец класс а может привести к небольшим проблемам, связанным с открытыми встроенными функциями, которые ссылаются па представление, Рассмотрим пример; с1аээ эгЭаге ( риЫсс ьл1 с(ау (( с о л э1 ( ге1игл с(, '1 0- рпоа1е 1лг д, лэ, у, 1эг ооэнРпи(ает сэа1елд здесь приведен совершенно правильный код на С+е, потому по функция, обьявленная в классе, может обращаться к любому члену класса так, как будто весь класс был полностью определен до рассмо~рения тела функции.
Однако это может быть не совсем очевэлдно чэлтающеьсу программу. Поэтому, я обычно либо помещаю данные в начало, либо определяю встраиваемые функции после класса. Например: с1аээ 1за1е ( риЫга сл1с(ау (1 солэ1, ,Ч-- рииаге. сл1с(, т, у; шале сл1 сга1е..с(ау (, 'солэ1 ( ге1игл И, ( 10.3. Эффективные типы, определяемые пользователем В предыдущем разделе обсуждалось проектирование класса сга1е в контексте описания базовых средств языка для определения классов. В этом разделе я смешаю акцент и описываю проектирование простого и эффективного класса тга1е, а также показываю, как средства языка способствуют такому проектированию. Небольппсе интенсивно используемые абстракции являются типичными для мнопэх приложений. Примерами могут служить латинские буквы, китайские иероэ лифы, целые, числа с плавающей точкой, комплексные числа, точки, указатели, координаты, преобразования, пары (уснпэалэель, глсеи(ения), даты, времена, диапазоны, связи, ассоциацэлээ, узльэ, пары (значение, едссница измерения), расположение на диске, местонахождение исходного кода, символы набора ВСП, валюты, строки, пряътугольники, масштабируемые числа с фиксированной точкой, дробные числа, строки символов, вектора и массээээы.
Каждое приложение использует что-нпбудь из этого перечня. Ловоээьно часто многие пз этих простых конкретных типов используются весьма интенсивно. Тнпичное приложение применяет некоторые из нпх непосредственно п гораздо большее количество — косвенно, через библиотеки. С++, как и другие языки программирования, непосредственно поддерживает некоторые из этих абстракций. Однако большинство подобных абстракшш не поддерлспвается, и не может поддерживаться непосредственно, потому что их слишком много. Более того, разработчик языка высокого уровня не может знать о всех запросах 2ВЗ 10 3 Эффективные типы, определяемые пользователем с1аяя Раге ( рибйс Г'1' открыспыд инте~фвт епит МолИ (!оп=!,~еб, так арг, паау, !ип, Ки(, аид, яер, ос1, поо, с(ес ), с1аяя ВасК с!аге (), // класс исключении 11' О ознп сает сиспольвуд внпчение сго уяовчаниюь Ра1е (т1 сЫ=О, Мои И т т =Мопй (0), !п1уу=0), КУ функнин сзосспупп к дтпе !п1 диу () сопя1, МопИ топИ () сопя1, !п1уеаг () сопя!, 0 со!роковое преостоел ение 0 со!роковое предс п!а вл ение в с!пи ге С яКггссуя1г!пу гер () сосся1, оо!Й сйиг гер (сбаг я(й сопя1, я1оги иоиК чес йе~аи11 (Кп!, МопЯ, Кпй, !!финк>(ии-,чодссфикоторы дтг!ы Ра1ейадд уеаг(Кп1п), Ра1ейадд топЯ (ЯКп), Ра1ей адд дау (пп и), 1~~ прнопвить и лет ,К,К прибавить из!есчс(ев /,К прибпвпть и днеи рг!оа1е !п10, т, у, яса1!сРо1е сКе~аиКК сКа1е, ), 0предссоовеение Этот набор операций весьма характерен для типа, определяемо~о пользователем; [1] Конструктор, определяюцц!й как должны быть проиннцналнзнрованы объекты/переменные данного типа.
[2] Набор функций доступа (функций-селекторов). Эти функции имеют модификатор сопя!, которьш указывает, ч го опи не должны изменять состояние объектову переменных, для которых онп вызваны. [3] Набор функпий-модификаторов. При их использовании не возникает необходимости разбираться в деталях представления или долго думать о смысле того плп иного члена данных. [4] Набор неявно определенныхопераций, позволяющих свободно копировать обьекты. [5] Класс Вас( да1е, используемый для сообщегшй об ошибках пхтем возбуждения исключений.
каждого приложения. Следовательно, пользователю должен бып предоставлен механизм определения небольших конкретных типов. Такие типы называются конкретнымн типами илц конкретными классами для того, чтобы отличить пх от абс грактных классов (4 13.3) п иерархий классов (й 12.2.4, й 12А). Олной пз главных целей при проектировании С '-ч было добиться качес ! вецнои поддержки определения н эффективного пспользовагшя типов, определяем!ах пользователем. Они являются фундаментом элегантного программирования. Как обычно. простое и обыденное статистически является гораздо более значимым, чем с ножное и утонченное.
В свете выщескааанного давайте создадим более качественный класс для представления дат: 284 Глава 10. Классы Я о1 ~ределпл тип Моп(Ь, чтобы не путаться в том, пишется ли, например, 7 шоня. как Ра(е)б, 7) (стиль, принятый в Ллеерпке) или Ра(е)7, 6) (европейский стиль). Я р 170.рзтакже использовал механизм ареументов по умолчанию. Я подумывал о том, чтобеа ввести отдельные типы Рау и Уеаг во избежание возможной путаницы типа РаЕе(1995, Еи1, 27) и Раге )27, 1и1, 1995). Однако этп типы ве настолько полезны, как Мопгй.