Les mécanismes de localisation ont été conçus de telle sorte que le programmeur peut, s'il le désire (et s'il en a réellement le besoin), personnaliser leur fonctionnement. Ainsi, il est parfaitement possible de définir de nouvelles facettes, par exemple pour permettre la localisation des types de données complémentaires définis par le programme. De même, il est possible de redéfinir les méthodes virtuelles des classes de gestion des facettes standards de la librairie et de remplacer les facettes originales par des facettes personnalisées. Cependant, il faut bien reconnaître que la manière de procéder n'est pas très pratique, et en fait les mécanismes internes de gestion des facettes semblent être réservés aux classes et aux méthodes de la librairie standard elle-même.
Comme il l'a été expliqué dans la Section 16.1, une facette n'est rien d'autre qu'une classe dérivant de la classe locale::facet et contenant une donnée membre statique id. Cette donnée membre est utilisée par les classes de locale pour identifier le type de la facette et pour l'intégrer dans le mécanisme de gestion des facettes standards.
L'exemple suivant montre comment on peut réaliser deux facettes permettant d'encapsuler les spécificités d'un type de donnée défini par le programme, le type answer_t. Ce type est supposé permettre la création de variables contenant la réponse de l'utilisateur à une question. Ce n'est rien d'autre qu'une énumération contenant les valeurs no (pour la réponse négative), yes (pour l'affirmative), all (pour répondre par l'affirmative pour tout un ensemble d'éléments) et none (pour répondre par la négative pour tout un ensemble d'éléments).
Dans cet exemple, deux facettes sont définies : la facette answerpunct, qui prend en charge la localisation des noms des différentes valeurs de l'énumération answer_t, et la facette answer_put, qui prend en charge le formatage des valeurs de cette énumération dans un flux standard. L'opérateur operator<< est également défini, afin de présenter la manière dont ces facettes peuvent être utilisées. La facette answer_get et l'opérateur correspondant operator>> n'ont pas été définis et sont laissés en exercice pour le lecteur intéressé.
Note : Cet exemple, bien que déjà compliqué, passe sous silence un certain nombre de points qu'il faudrait théoriquement prendre en compte pour réaliser une implémentation correcte des facettes et des opérateurs d'insertion et d'extraction des données de type answer_t dans les flux standards. Il faudrait en effet traiter les cas d'erreurs lors des écritures sur le flux de sortie dans la méthode do_put de la facette answer_put, capter les exceptions qui peuvent se produire, corriger l'état du flux d'entrée / sortie au sein de l'opérateur operator<< et relancer ces exceptions.
De même, les paramètres de la locale ne sont absolument pas pris en compte dans la facette answerpunct, alors qu'une implémentation complète devrait s'en soucier. Pour cela, il faudrait récupérer le nom de la locale incluse dans les flux d'entrée / sortie d'une part, et définir une facette spécialisée answerpunct_byname, en fonction du nom de laquelle les méthodes do_yesname, do_noname, do_allname et do_nonename devraient s'adapter. La section suivante donne un exemple de redéfinition d'une facette existante.
La redéfinition des méthodes de facettes déjà existantes est légèrement plus simple que l'écriture d'une nouvelle facette. En effet, il n'est plus nécessaire de définir la donnée membre statique id. De plus, seules les méthodes qui doivent réellement être redéfinies doivent être récrites.
L'exemple suivant présente comment un programme peut redéfinir les méthodes do_truename et do_falsename de la facette standard numpunct_byname afin d'en fournir une version localisée en français. Cela permet d'utiliser ces noms français dans les opérations de formatage des flux d'entrée / sortie standards, lorsque le manipulateur boolalpha a été utilisé.
Note : La classe de base de la facette MyNumpunct_byname est la classe numpunct_byname parce que la facette a besoin de connaître le nom de la locale pour laquelle elle est construite. En effet, aucun autre mécanisme standard ne permet à une facette de récupérer ce nom et donc de s'adapter aux différentes locales existantes. Vous remarquerez que les facettes de formatage n'ont pas besoin de connaître ce nom puisqu'elles peuvent le récupérer grâce à la méthode name de la locale du flux sur lequel elles travaillent.
La facette MyNumpunct_byname utilise la fonction setlocale de la librairie C pour récupérer le nom de la locale courante si elle est initialisée avec un nom vide. En réalité, elle devrait récupérer ce nom par ses propres moyens et effectuer les traductions des noms des valeurs true et false par elle-même, car cela suppose que la locale globale du programme est initialisée avec le même nom. C'est pour cela que le programme principal commence par appeler la méthode global de la classe local avec comme paramètre une locale anonmyme. Cela dit, les mécanismes permettant à un programme de récupérer les paramètres de la locale définie dans l'environnement d'exécution du programme sont spécifiques à chaque système et ne peuvent donc pas être décrits ici.
Bien entendu, si d'autres langues que le français devaient être prises en compte, d'autre mécanismes plus génériques devraient également être mis en place pour définir les noms des valeurs true et false afin d'éviter de compliquer exagérément le code de la facette.
Précédent | Sommaire | Suivant |
Les facettes standards | Niveau supérieur | Les conteneurs |