C++之国际化(4)

转载自:http://hi.baidu.com/nicker2010/item/a92b38eb4f918d3087d9deeb

 

所有标准库版本的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

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值