## 4.6 新しい基底ファセットクラスの作成

必要に応じて、既存のファセットをまったく表示せずに、ロケールに新しいファセットオブジェクトを追加することができます。そのためには、新しい基底ファセットクラスを定義する必要があります。

次に示すのは、そういった新しいファセットクラスの例です。これは、文字がドイツ語のウムラウト、すなわち特殊文字 `äöüÄÖÜ` のいずれかなのかを確認するサービスを提供するファセットです。

>     class Umlaut : public locale::facet {                         //1
>       public:
>         static locale::id id;                                     //2
>         bool is umlaut(char c) { return do_isumlaut(c);}          //3
>         Umlaut(size_t refs=0): locale::facet(refs) {}             //4
>       protected:
>         virtual bool do_isumlaut(char);                           //5
>     };

//1 | 基底ファセットクラスはいずれも、基底ファセットクラス locale::facet から派生したものとします。
//2 | また、基底ファセットクラスの内容は、いずれも固有の `id` という名前で、 `locale::id` という型の静的メンバーとします。ロケールシステムでは、このオブジェクトを内部的に使用して、この型のファセットを格納するスロットをロケールオブジェクト内で指定します。 (派生ファセットクラス自体には固有の `id` メンバーはありません。そのかわり、基底ファセットクラスからメンバーを継承するので、基底クラスと同じスロットに格納されます。)
//3 | 保護仮想関数 do_umlaut を呼び出した結果を返すメンバー関数 is_umlaut() を宣言します。
//4 | コンストラクタは `refs` パラメータを使用します。これは基底クラス `locale::facet` に渡り、先に説明したように、寿命を制御します。
//5 | 文字がウムラウトかどうかを実際に判断する機能は、保護仮想メンバー関数に実装します。一般には、必要に応じて派生ファセットを無効にすることができるように、ファセット内のどの地域対応サービスもこのように仮想関数で実装すべきです。

次に、図 12 に示すように、新しい型のファセットでロケールを作成します。

#### 図 12 -- ロケールへの新しいファセットの追加

この手順のコードは、次のとおりです。

>     locale loc(locale(""),  // ネイティブロケール
>                new Umlaut); // 新しいファセット                      //1
>     char c,d;
>     while (cin >> c){
>      d = use_facet<ctype<char> >(loc).tolower(c);                 //2
>      if (has_facet<Umlaut>(loc))                                  //3
>      { if (use_facet<Umlaut>(loc).is umlaut(d))                   //4
>            cout << c << "belongs to the German alphabet!" << '\n';
>      }
>     }

//1 | ロケールオブジェクトは、新しいファセットクラスのインスタンスで作成されます。ロケールオブジェクトには、ネイティブロケールオブジェクトと、新しいファセットクラス Umlaut のインスタンスにあるすべてのファセットオブジェクトが設定されます。
//2 | 新しい umlaut ファセットクラスは、小文字しか処理できないという制限を想定します。したがって、umlaut ファセットオブジェクトに文字を渡す前に、すべて小文字に変換する必要があります。これは、ctype ファセットオブジェクトのサービス関数 tolower() で処理します。
//3 | umlaut ファセットオブジェクトを使用するには、そのオブジェクトがロケールにあるかどうかを確認する必要があります。このような簡単な例であればすぐに分かることですが、実際のアプリケーションでは、非標準ファセットオブジェクトの有無を使用前に確認しておいてください。
//4 | umlaut ファセットオブジェクトを使用して、そのメンバー関数 umlaut() を呼び出します。この新しく作成したファセットオブジェクトは、標準 ctype ファセットを使用する構文とまったく同じです。

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

OEM リリース, 1998 年 6 月