## 4.1 ファセットの型

ファセットは、ロケールに保存して、型によって検索するオブジェクトです。ファセットは、文化や言語に依存するデータをカプセル化します。また、ここにはカプセル化したデータを使用するサービス (関数) をおさめることができ、プログラムの国際化に使用します。

標準 C++ ライブラリでは、多くのファセットクラスを定義します。これらを標準ファセットと呼びます。前章で説明したように、すべてのロケールにファセットがあります。標準ファセットの動作を変更することで、ユーザー定義の派生ファセットを作成することもできます。また、標準ファセットでは対応できない国際化の側面を処理するための、まったく新しいファセットクラスを作成することもできます。これらのプロセスについては、この章で後述します。

ファセットクラスの説明では、基底ファセットと派生ファセットの違いを認識する必要があります。基底ファセットとは、次の属性を持つクラスです。

- クラス `locale::facet` から派生したクラスです。
- `id` という名で `locale::id` という型の静的データメンバーを持っています。

以上の属性により、ファセットをロケールに保存して、その型によって検索することができます。ロケールには、基底ファセット型ごとに少なくとも 1 つのファセットがあります。

派生ファセットは、基底ファセットから派生したクラスですが、それ自体に固有の静的な `locale::id` メンバーがあるわけではなく、派生元の基底ファセットから継承したものです。他のファセットと同様に、派生ファセットもロケールに格納することができますが、ロケールでは基底ファセットと同じスロットを使用し、スロットにある他のファセットに置き換わります。

たとえば、以下のコード例は、mythical (架空の) 基底ファセットと、そこから派生したファセットを定義したものです。ロケールにそれらのファセットをどのように格納し、そこからどのように検索するかを示しています。

>     class mythical: public locale::facet {                         //1
>      public:
>       static locale::id id;
>       ... // etc
>     };

>     class mythical_byname: public mythical {                       //2
>      public:
>       mythical_byname (char *name,/*etc*/); // Constructor
>       ... // etc
>     };

>     int main (void) {
>       locale loc0(locale::classic());                              //3
>       locale loc1(loc0,new mythical);                              //4
>       locale loc2(loc1,new mythical_byname("he_DO"));              //5
>       const mythical &m2=use_facet<mythical>(loc2);                //6
>       const mythical &m1=use_facet<mythical>(loc1);                //7
>       const mythical &m0=use_facet<mythical>(loc0);                //8
>     }

//1 | 基底ファセットクラスの例。`locale::facet` から派生し、名前が `id` の静的 `locale::id` メンバーを持つクラスです。
//2 | 派生ファセットクラス。
//3 | クラシックロケールのコピー。他のロケールと同様に、多くのファセットがあります。それらのファセットは、対応する基底ファセット型の設定によってインデックス付けされたスロットに格納されます。したがって、基底ファセット型 `mythical` のスロットは 1 つだけであり、このクラシックロケールでは、`mythical` スロットは空です。
//4 | クラシックロケール `loc0` のコピー。その `mythical` スロットは、新しく作成された `mythical` ファセットで占められています。
//5 | `loc1` のコピーですが、`mythical` スロットの中身は、新しく作成された `mythical_byname` ファセットに置き換わりました。
//6 | `//5` で作成した `mythical_byname` ファセットまでの参照を返します。ただし、このコンテキストでは不自然ですが、RTTI を使用していないため、`mythical_byname` ファセットかどうかを知る方法はありません。ここで言えることは、ロケールの `mythical` スロットから派生した `mythical` ファセットであるということだけです。`use_facet` 関数テンプレートの詳細については、この章の後半を参照してください。
//7 | これは `//4` で作成した mythical ファセットまでの参照を返します。
//8 | `runtime_error` 例外の送出が発生します。`loc0` の `mythical` スロットが空のためです。

ライブラリに添付されている標準ファセットは、すべてクラステンプレートとして定義されています。最初のテンプレートパラメータは、常にファセットが使用する文字型であり、通常は `char` か `wchar_t` です。ファセットによっては、追加のテンプレートパラメータを使用します。基底ファセットと派生ファセットの違いのもう 1 つの例として、テンプレートパラメータが 1 つである標準ファセットテンプレート `numpunct` の主な部分だけを示します。

>     template <class charT>
>     class numpunct: public locale::facet {
>      public:
>       static locale::id id;
>       ... // etc
>     };

>     template <class charT>
>     class numpunct_byname: public numpunct<charT> {
>       ... // etc
>     };

一般に、これらのテンプレートは `char` や `wchar_t` でインスタンス化するため、基底ファセット型は次のようになります。

>     numpunct<char>
>     numpunct<wchar_t>

また、派生ファセット型は次のようになります。

>     numpunct_byname<char>
>     numpunct_byname<wchar_t>

アプリケーションで専用の文字型 `my_char_t` を作成すると、`numpunct<my_char_t>` が基底ファセット型になり、`numpunct_byname<my_char_t>` が派生ファセット型になります。

Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。

OEM リリース, 1998 年 6 月