博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++之国际化(4)
阅读量:4198 次
发布时间:2019-05-26

本文共 2284 字,大约阅读时间需要 7 分钟。

转载自:

 

所有标准库版本的locale中都必须包含某些标准的facet

除此之外,用户可以安装属于自己的facet,或者替换标准的facet

我们怎么产生自己的facet呢?

任何一个类型F,只要满足一下两个条件,就可以作为facet:
1. F以public形式派生自locale::facet.
   facet主要定义了一些机制,共locale对象内部的引用计数器使用。
   此外还将拷贝构造和拷贝复制函数声明为private,
   禁止外界拷贝facet,也禁止外界对facet赋值
2. F必须拥有一个型别为locale::id的public static member,名为id.
   此成员用来“以某个facet型别为索引,搜索locale之内的一个facet”

   下面是CodeBlocks中facet的源码(id的实现在locale中):

  class locale::facet
  {
  private:
    friend class            locale;
    friend class            locale::_Impl;
    mutable _Atomic_word _M_refcount;
    static __c_locale       _S_c_locale;
    static const char  _S_c_name[2];
#ifdef __GTHREADS
    static __gthread_once_t _S_once;
#endif
    static void _S_initialize_once();
  protected:
    explicit facet(size_t __refs = 0) throw() : _M_refcount(__refs ? 1 : 0)
    { }
    virtual ~facet();
    static void _S_create_c_locale(__c_locale& __cloc, const char* __s,
         __c_locale __old = 0);
    static __c_locale _S_clone_c_locale(__c_locale& __cloc);
    static void _S_destroy_c_locale(__c_locale& __cloc);
    static __c_locale _S_get_c_locale();
    static const char* _S_get_c_name();
  private:
    inline void _M_add_reference() const throw()
    { __gnu_cxx::__atomic_add(&_M_refcount, 1); }

    inline void _M_remove_reference() const throw()

    {
      if (__gnu_cxx::__exchange_and_add(&_M_refcount, -1) == 1)
   {
     try
     { delete this; }
     catch (...)
     { }
   }
    }
    ///私有的拷贝构造和拷贝复制函数
    facet(const facet&);
    facet& operator=(const facet&);
  };
   标准facet不仅仅遵循上述两条机制,还遵循一些特殊原则。
   如果能做到这些原则,还是好处多多。这些原则包括:
   1. 所有的成员函数均声明为const.
   2. 所有的public成员函数均不是虚函数,而是将调用操作委托给一个protected函数,
      后者的命名类似于对应的public函数,只不过在前面家霍桑do_
      如numpunct::truename会调用numpunct::do_truename()
      因此,如想改变某个facet,应该改写其对应的protected函数

下面是numpunct类的源码,来源于MSDN,从中也可以看到上面说的两条原则:

template<class E>

class numpunct : public locale::facet
{
public:
    typedef E char_type;
    typedef basic_string<E> string_type;
    explicit numpunct(size_t refs = 0);
    E decimal_point() const;
    E thousands_sep() const;
    string grouping() const;
    string_type truename() const;
    string_type falsename() const;
    static locale::id id;
protected:
    ~numpunct();
    virtual E do_decimal_point() const;
    virtual E do_thousands_sep() const;
    virtual string do_grouping() const;
    virtual string_type do_truename() const;
    virtual string_type do_falsename() const;
    }

    大部分标准facet都定义了一个"_byname"版本。这个版本派生自标准的facet。

    被用来根据locale名称产生出相应的facet。
    如class numpunct_byname被用来针对一个有名称的locale产生一个numpunct facet

 

你可能感兴趣的文章
【计算机网络 第五版】阅读笔记之二:物理层
查看>>
【计算机网络 第五版】阅读笔记之三:数据链路层
查看>>
【计算机网络 第五版】阅读笔记之四:网络层
查看>>
【计算机网络 第五版】阅读笔记之五:运输层
查看>>
【一天一道LeetCode】#77. Combinations
查看>>
【一天一道LeetCode】#78. Subsets
查看>>
【一天一道LeetCode】#79. Word Search
查看>>
【一天一道LeetCode】#81. Search in Rotated Sorted Array II
查看>>
【数据结构与算法】深入浅出递归和迭代的通用转换思想
查看>>
【一天一道LeetCode】#83. Remove Duplicates from Sorted List
查看>>
【一天一道LeetCode】#91. Decode Ways
查看>>
【一天一道LeetCode】#92. Reverse Linked List II
查看>>
【一天一道LeetCode】#93. Restore IP Addresses
查看>>
【一天一道LeetCode】#94. Binary Tree Inorder Traversal
查看>>
【一天一道LeetCode】#112. Path Sum
查看>>
【一天一道LeetCode】#113. Path Sum II
查看>>
【一天一道LeetCode】#114. Flatten Binary Tree to Linked List
查看>>
【unix网络编程第三版】阅读笔记(二):套接字编程简介
查看>>
【一天一道LeetCode】#115. Distinct Subsequences
查看>>
【一天一道LeetCode】#116. Populating Next Right Pointers in Each Node
查看>>