Интернационализация. Строение фацетов

   
На этом шаге мы приведем требования и рекомендации по созданию собственных фацетов.

   
Возможности локального контекста определяются содержащимися в нем фацетами. Все локальные контексты заведомо содержат минимальный набор
стандартных фацетов. В описаниях отдельных фацетов, приведенных далее, указано, какие специализации гарантированно присутствуют в контексте.
Помимо перечисленных реализация стандартной библиотеки C++ может включить в локальный контекст дополнительные фацеты. Важно
понимать, что пользователь также может добавить собственные фацеты или установить их вместо стандартных фацетов.
На 533 шаге рассматривается процедура установки фацета в локальном контексте. Например, класс germanBoolNames
был объявлен производным от класса numpunct_byname<char> одного из стандартных фацетов и установлен в локальном контексте при
помощи конструктора, в аргументах которого передаются локальный контекст и фацет. Но что нужно для того, чтобы создать собственный фацет?
В качестве фацета может использоваться любой класс F, удовлетворяющий двум требованиям.

  • Класс F является открытым производным от класса locale::facet. Базовый класс в основном определяет механизмы подсчета
    ссылок, используемые во внутренней работе объектов локального контекста. Кроме того, он объявляет закрытыми копирующий конструктор и
    оператор присваивания, что предотвращает копирование или присваивание фацетов.
  • Класс F содержит открытую статическую переменную id типа locale::id. Эта переменная используется для поиска
    фацета в объекте контекста по его типу. Применение типа в качестве индекса прежде всего направлено на обеспечение типовой безопасности интерфейса.
    Во внутреннем представлении для работы с фацетами используется обычный контейнер с целочисленными индексами.

   
Стандартные фацеты соответствуют не только этим требованиям, но и некоторым специальным рекомендациям - не обязательным, но весьма полезным.

  • Все функции класса объявляются константными. Это полезно, поскольку функция use_facet() возвращает ссылку на константный фацет.
    Функции, не объявленные константными, вызываться не могут.
  • Все открытые функции объявляются невиртуальными и передают запросы защищенным виртуальным функциям. Имя защищенной функции совпадает
    с именем открытой функции, с добавлением префикса do_. Например, функция numpunct::truename() вызывает функцию
    numpunct::do_truename(). Подобная схема выбора имен помогает избежать замещения функций при переопределении только одной из
    нескольких виртуальных функций с одинаковыми именами. Например, класс num_put содержит несколько функций с именем put.
    Кроме того, программист базового класса может включить в невиртуальные функции дополнительный код, который будет выполняться даже в случае
    переопределения виртуальных функций.

   
Следующее описание стандартных фацетов относится только к открытым функциям. Чтобы изменить фацет, всегда приходится переопределять соответствующие
защищенные функции. Определение функций с таким же интерфейсом, как у открытых функций фацета, всего лишь перегрузит их, поскольку эти
функции не являются виртуальными.

   
Для большинства стандартных фацетов определяется версия с суффиксом _byname. Она является производной от стандартного фацета и
создает специализацию для соответствующего имени локального контекста. Так, класс numpunct_ byname создает фацет numpunct для
локального контекста с заданным именем. Например, команда создания немецкого фацета numpunct может выглядеть так:

  std::numpunct_byname("de_DE")

   
Классы _byname создаются в процессе внутренней работы конструкторов локального контекста, получающих имя в виде аргумента. Для
каждого стандартного фацета, поддерживающего имя, конструирование экземпляра этого фацета производится соответствующим классом _byname.

   
На следующем шаге мы рассмотрим числовое форматирование.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий