Бьерн Страуструп. Язык программирования С++. Специальное издание (2011) (1004033), страница 216
Текст из файла (страница 216)
ипЬие (1оса1е ( "уг" ) ) з // французский ору (11п«1оиз) з // читаем американский английский, пишем французский 3зп2.!тЬие(1оса(е("1г") ) ) //французский 1оиз2. !тЬие (!оса!е (" еп ЮБ" ) ) э // американский английский ору(1!п2,1ои(2); //читаем французский, пишем американский английский Тогда для потоков Арг 12, 1999 1000.3 Арг 13, 1999 345.45 Арг 14, 1999 9600.321 31иШез 1950 10, 3 3 1иШег 1951 134, 45 3 1иШег 1952 67, 9 эта программа породит вывод 12 аггп 1999 1000, 3 13 агп1 1999 345, 45 14 аггц 1999 9688,321 Хи!у 3 1950 10.3 Уи!у 3, 1951 134.45 Хи(у 3, 1952 67.9 Оставшаяся часть настоящего приложения в основном описывает механизмы, делающие подобную схему работы возможной, и объясняет, как их нужно применять.
Отметим, что у большинства программистов нет причин разбираться в мельчайших деталях локальных контекстов. Многие программисты никогда не манипулируют объектами 1оса1е явным образом, а те, что все-таки выполняют такую работу, просто извлекают стандартный 1оса!е и закрепляют его за потоком (Э2!.7). В то же время, механизмы, обеспечивающие создание таких объектов и возможность их простого использования представляют из себя небольшой язык программирования. А если программа или система оказались успешными, они в обязательном порядке будут использоваться людьми, потребности и предпочтения которых проектировщики не предвидели. Большинство успешных программ будут использоваться в странах, естественные языки и наборы символов в которых отличаются от таковых для оригинальных (исходных) проектировщиков и программистов.
Широкое ().2. Класс !оса!е 1011 применение программы является признаком успеха программы, так что проектирование и программирование, нацеленные на преодоление языковых и культурных барьеров, являются необходимыми предпосылками для успешной работы. Концепция локализации (интернационализации) проста. Но многочисленные практические детали изрядно запутывают дизайн и реализацию объектов !оса!е: 1.
Объекты 1оса1е должны инкапсулировать национальные стандарты, такие как, например, форма отображения дат. Подобные национальные соглашения варьируются непостижимым и нерегулярным образом. Они не имеют ничего общего с языками программирования, и поэтому язык программирования не может стандартизовать их. 2. Концепция локализации должна быть расширяемой, поскольку невозможно исчерпывающе перечислить все особенности, присушие всем национальным культурам, и представляющие интерес для пользователей С++. 3.
Объекты 1оса1е используются в операциях ввода/вывода, от которых требуется высокая эффективность на этапе выполнения. 4. Локализация должна быть прозрачна для большинства программистов, желаюших просто воспользоваться правильно работаюшим вводом/выводом, и не желающих разбираться в том, как все это в точности устроено. 5. Локализация должна быть доступна разработчикам средств, имеюших дело с зависящей от национальных особенностей информацией в рамках, выходящих за пределы стандартных потоков ввода/вывода. Проектирование программы, имеюшей дело с вводом/выводом, имеет выбор между управлением форматированием при помоши «обычного кода», или при помоши объектов !оса1е. Первый (более традиционный) подход приемлем в случаях, когда мы уверены, что каждая операция ввода может быть легко преобразована из одной системы соглашений в другую.
Однако если нужно менять формы отображения встроенных типов, или если требуются разные символьные наборы, или набор соглашений может расширяться, то становится привлекательным подход с объектами 1оеа1е. В общем случае !оса1е составляется из фасетов, контролирующих индивидуальные аспекты соглашений, таких как символы-разделители для отображения чисел с плавающей запятой (зуев!пза1 оо!аг(); 513.4.2) или формат, применяемый для чтения денежных величин (топеураасг Ззл.4.3).
Фасет является объектом класса, производного от класса !оса!е::/асег (5О.З). Мы можем рассматривать 1оса1е как контейнер фасетов 513.2, 513.3.1). Класс !оса1е и связанные с ним средства представлены в заголовочном файле <1оса1езс е!авл лЫ:: !оса!е ( риЫ!е: е!алл /асеев //тип для представления фасетов; ЗР.З с!азл Ы; ~У тип для идентификации локализаций; ЗР.З Гуре«!е! !пг еагееогуз /з тип для разбиения фаеетов на категории Приложение ().
Локализация 1012 з(айс сопз( Са(еаогу //настоя<цие значЕНиЯ ЗаВиСЯт От рЕалиЗации попе = О, соИа(е = 1, с(уве = 1«1, и у=1«г, литепс = 1«З, Йле = 1«4, тетаяез = 1«5, аИ = соИа(е ) с(уре ) толеаиу ) литепс ) Йпе ) теззаеез/ 1оса1е () Йгон () ( Р копирует глобальную локализацию фВ.2.!) !оса(е(сопл(!оса(еь х) (Ьго<г() ( Икопирует х ехрдп( 1оса(е (солт сьаг* р) ( //копия локализации с именем р ЯВ.2 !) -!оса(е() Йгон () // копия х плюс фасеты с из р И калия х плюс фасеты с из у (оайе (сопл( (ость х, сопл( слог* р, стееогу с) ( (оса!е (солт !оса!еь х, сопл( !оса(еь у, са<ееогу с) ( (етр1а(в<с<аз< саге(> <опйе (соп(е Ьзса(еь х, гасе( 2) 1 Икания х плюс фасет) (етр(а1е<с<азз гасе<> 1оса1е сотЬ<пе(сопл( (оойеь х) ( //копия *<ЬИ плюс гасе( из х сопл( !оса!еь орега(ог= (со з1 (оса<еь х) Йгон (); Ьоо( врага(ос== (сопл( 1ос<йеь ) сопл<; р сравнение локалшаций Ьоо! ореплог) = (сопл( 1оса!еЬ) соп(а< //или данной локалшации ЯР2.
!) з1пле пате () сопл(( <етр!а(е<с1азз СЬ, с!азз Тг, с(азз А> // сравнение строк в данной локализации Ьоо( орегаюг() (сопл(Ьаз!с з(пле<СЬ, Тг,А>ь, сопл(Ьаз!с з(пле<СЬ, Тг,А>ь) сопл(( ,Чует-ка новой глоб-ой лакал-ии и возвр. спи<рой // "классическая" локализация в С-стиле геалс 1оса(е е1оЬа( (соп(а !оса!еь ) ( з(айс сопл< (оса(еь сйпйс (); рпза(е: И гергезел<алол соИа(е< слог> ." 1оса(е < Тип )оса!е можно рассматривать как интерфейс к тар<Ы,уасе< >, то есть как нечто, позволяющее нам использовать !оса!е:: Ы для нахождения соответствующего объекта класса, производного от !оса!е: < (асс(. Истинная реализация класса 1оса1е является эффективным вариантом этой идеи. Схема выглядит примерно следующим образом: 0.2.
Класс )оса(е 1013 Здесь со!!иге<айаг> и иитриис!<сааг> являются стандартными библиотечными фасетами игл.4). (чак и любые фасеты, они наследуют от 1оса1е: 4асе!. Полагается, что объекты 1оса1е (объекты локализации, объекты локального контекста) можно легко и дешево копировать. Отсюда следует, что класс 1оса1е почти наверняка является дескриптором к специализированному тор<!И, !асят" >, представляющему собой основную часть реализации. Доступ к фасетам объектов локализации должен осуществляться быстро и эффективно, так что специализированный тар<Ы, !асег" > должен быть оптимизирован для быстрого доступа наподобие массива.
Доступ к фасету объекта 1оса1е выполняется в нотации изе )асег<Гасег (1ос) (см. 9Э.3.1). Стандартная библиотека предоставляет богатый набор фасетов. Чтобы помочь программисту ориентироваться в стандартных фасетах, они группируются в категории, такие как иитет!с или со!!аге (взл.4). Программист может заменять фасеты в существующих категориях (5О.4, 5О.4.2.1). Нет, однако, возможности добавлять новые категории (нет возможности определить новую категорию программным путем). Понятие категории фасетов относится только к фасетам стандартной библиотеки и не является расширяемым. Фасет не обязан принадлежать к какой-либо категории, так что многие пользовательские фасеты и не принадлежат им. По большей части локализация (неявно) используется в потоках ввода/вывода.
У каждого !зггеат и ози еат есть свой 1оса1е. По умолчанию, поток получает глобальный 1оса1е (багз.2.1) в момент создания потока. Задать локализацию потока можно при помощи функции 1тЬие (), а извлекается копия !оса!е потока при помощи функции яе!!ос() 521.6.3). 0.2.1. Локальные контексты с заданными именами Объекты!оса1е конструируются из других!оса1е и фасетов. Самым простым способом их создания является копирование. Например: й' копия текущей глобальной локализации ЦР.2.3) 1оса1е 1осйг 1! копия текущей глобальной локализации (ЗР.2.3) У копия "локализации, предпочитаемой пользователем" 1оса(е!ос1 = 1оса1е (); !оса!в 1ос2 ( " " ); !оса!е 1ос3 ( "С" ); д' копия "С"-локализации !оса!е 1ос4 = !оса(е::с!азз!с (); д'копия "Со<локализации 1осаге 1ос5 (" РОЯ!Х" ); У копия "Р031Х"-локализации, задаваемой реализацией Смысл !оса1е("С" ) задается стандартом как классический контекст локализации языка С; именно он подразумевался на протяжении всей книги.
Остальные имена контекстов локализации определяются реализациями. Полагается, что 1оса1е (" " ) задает контекст локализации, предпочтительный для пользователя системы, который формируется не языковыми, а системными средствами. В большинстве операционных систем имеются свои собственные средства формирования контекста локализации программы.