Tools.h++ 7.0 ユーザーズガイド: 1 - クラスの概要

Copyright 1999 Rogue Wave Software
Copyright 1999 Sun Microsystems, Inc.

# クラスの概要 | # 1 |

この章では、Tools.h++ の概要を説明するとともに、クラス間の共通性についていくつか要点を取り上げて解説します。

Tools.h++ が提供するのは、方針ではなく実装です。したがって、Tools.h++ の大部分は、大規模で充実した具体クラスのセットです。これらのクラスは、自身の実装や意味に関しては他のクラスに依存せず、独立して使用できるようになっています。このため、一度に 1、2 個だけ抜き出して使用できます。具体クラスは Tools.h++ のもっとも重要な部分です。

また、Tools.h++ には、充実した抽象基底クラスのセットも入っています。抽象クラスは、持続性や国際化、その他の問題に対するインタフェースを定義しています。さらに、これらのインタフェースを実装する多数の実装クラスも入っています。実装クラスは公開ですが、非公開クラスと同様に機能します。実装クラスは、使用を目的として設計されていないため、ここでは説明しません。

Tools.h++ クラスの中には、コレクションクラス (あるいはコレクション) としてさらに分類されるものがあります。Tools.h++ の中心的な機能であるコレクションクラスは、次の 3 つのグループに分類されます。

- テンプレートにもとづくコレクションクラス。短縮して、コレクションクラステンプレート、または単にテンプレートとも呼ばれます。
- 総称コレクションクラス
- Smalltalk 式コレクションクラス

コレクションクラスは通常、その実装に関係なく、Smalltalk の命名規則と意味モデルの SortedCollection、Dictionaries、Bags、Sets などに従っています。これらは同じようなインタフェースを使用しており、簡単に交換できるようになっています。テンプレートにもとづいたコレクションと総称コレクションは、どのような種類のオブジェクトにも対応します。Smalltalk 式コレクションでは、まとめられるすべての項目が RWCollectable から継承されなければなりません。

プログラムで使用するコレクションクラスの選択は、非常に難しい仕事です。このマニュアルでは、各自の目的に最適のクラスを判断する際に役立つ、「コレクションの選択」という付録を付けてあります。

この章の最後にある表 1-2 には、Tools.h++ の全公開クラスのクラス階層を示しています。これらの公開クラスだけでなく、Tools.h++ には、その内部使用のためのクラスも含まれています。

## 具体クラス

具体クラスは次のもので構成されています。

- 日付、時刻、文字列などを表わす単純クラス。第 3 〜 5 章で説明します。
- テンプレートにもとづくコレクションクラス。第 10 章「コレクションクラステンプレート」で説明します。
- プリプロセッサの `<generic.h>` 機能を使用する総称コレクションクラス。第 11 章「総称コレクションクラス」で説明します。

### 単純クラス

Tools.h++ には、軽量な単純クラスの充実したセットが用意されています。軽量とは、初期設定子とコピーコンストラクタが低コストであるということをいいます。これらのクラスには、RWDate (日付)、RWTime (時刻、さまざまなタイムゾーンとロケールをサポートする)、RWCString (単一バイト文字列と複数バイト文字列)、RWWString (ワイド文字列)、RWCRegexp (正規表現) があります。これらのクラスのほとんどの大きさは 4 バイト以下であり、非常に単純なコピーコンストラクタ (通常は単なるビットコピー) をもち、仮想関数はありません。『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』を参照してください。

### テンプレートにもとづくコレクションクラス

テンプレートにもとづくコレクションクラス、つまり「テンプレート」を使用すると、高速化と型の安全使用が可能になります。テンプレートを慎重に使用すれば、コードサイズを非常に小さくすることもできます。ただし、テンプレートを多数の異なる型で使用すると、コードサイズが大きくなる可能性があります。これは、各型が実際に新しいクラス全体を生成するためです。コンパイラで標準 C++ ライブラリを使用できる場合は、標準 C++ ライブラリにもとづく、Tools.h++ のテンプレートにもとづくコレクションクラスを使用することができます。コンパイラが、標準 C++ ライブラリにアクセスできない場合でも、140 ページの「標準 C++ ライブラリが必要ない場合」と 167 ページの「標準ライブラリなしでテンプレートを使用する」の説明に従って、テンプレートのサブセットを使用することができます。

### 総称コレクションクラス

総称コレクションクラスとは、各自の C++ コンパイラに提供されている `<generic.h>` プリプロセッサマクロを使用するクラスのことをいいます。これらは型保証であるという点で、テンプレートをサポートしないコンパイラに対してテンプレートに近い機能を提供します。したがって、非常に移植性の高いものです。ただし、プリプロセッサへの依存度が高いため、これらのクラスを含むコードへのデバッガの使用が困難になる可能性があります。詳細については、第 11 章「総称コレクションクラス」を参照してください。

## 抽象基底クラス

Tools.h++ には、抽象基底クラスとそれに対応する特殊化クラスのセットが含まれており、多数の問題に対して枠組みを提供します。次の表は、これらの問題のいくつかを示して、それらの問題に各抽象基底クラスを対応付けています。『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』の各クラスの説明は、それが抽象基底クラスかどうかを示します。

#### 表 1-1 抽象基底クラスと問題

問題 | クラス | 説明箇所
--- | --- | ---
ロケール | RWLocale | 374 ページの「RWLocale と RWZone」
タイムゾーン | RWZone | 374 ページの「RWLocale と RWZone」
仮想ストリーム | RWvistream RWvostream | 第 5 章「仮想ストリーム」
多相持続性 | RWCollectable | 第 13 章「持続性」
仮想ページヒープ | RWVirtualPageHeap | 『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』
モデルビューコントローラ抽象 | RWModel RWModelClient | 『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』

## Smalltalk 式コレクションクラス

Tools.h++ の Smalltalk 式コレクションクラスには、C++ の長所と短所とともに、Bag や SortedCollection のように Smalltalk と同名の機能が多数備わっています。Smalltalk 式コレクションの最大の長所は、その単純なプログラミングインタフェース、強力な入出力機能、コードの再利用性の高さにあります。最大の短所は、型保証が不十分であり、オブジェクトコードサイズが比較的大きいということです。これらのクラスは、わずかに使用されただけでも、初期化のための機械命令のオーバーヘッドが高いため、通常大きくなります。Smalltalk 式コレクションクラスで使用するすべてのオブジェクトは、抽象基底クラス RWCollectable から継承しなければなりません。

## 共通のメンバー関数

各クラスのプログラミングインタフェースはすべてよく似ています。この節では、この共通機能について説明します。

### 持続性

次のメンバー関数は、`ClassName` 型のオブジェクトを、`RWFile` と RogueWave の仮想ストリーム機能との間で格納および復元するために、使用されます。

      RWFile&      operator<<(RWFile& file, const ClassName&);
      RWFile&      operator>>(RWFile& file,       ClassName&);
      Rwvostream&  operator<<(RWvostream& vstream,const ClassName&);
      Rwvistream&  operator>>(RWvistream& vstream,  ClassName&);

クラス `RWFile` は ANSI C ファイル入出力をカプセル化します。これについては、第 6 章「クラス RWFile の使用法」と『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』および第 6 章で詳しく説明します。`RWFile` を使用して保存されるオブジェクトはバイナリ形式で保存されるので、ファイルの記憶および取り出しが効率化されます。

クラス `RWvistream` と `RWvostream` は、RogueWave の仮想ストリーム機能で使用される抽象基底クラスです。最終的な出力形式は特殊化クラスによって決定されます。たとえば、`RWpistream` と `RWpostream` は、それぞれ `RWvistream` と `RWvostream` から派生するクラスですが、これらは "可搬性がある ASCII 形式" を使用してオブジェクトを格納したり取り出すことができます。この結果、異なるオペレーティングシステムの間で転送することができます。これらのクラスについては、第 5 章「仮想ストリーム」および『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』で詳しく説明します。

RWFiles と Rogue Wave ストリームのどちらに格納するかは、ユーザーが決定することです。RWFiles に格納する場合、速度の点では優れていますが、その結果の可搬性がホストのマシンとオペレーティングシステムに制限されます。Rogue Wave ストリームに格納する場合、速度の点では劣っていますが、いくつかの特殊化クラスを得ることができます。これらのクラスは、異なるマシン間で可搬性の高い形式、分散計算のための XDR ストリームカプセル化などの便利な機能を提供します。

### 記憶サイズ

次の共通メンバー関数は、型 `ClassName` のオブジェクトを格納するために必要な二次記憶のバイト数を RWFile に返します。

        Rwspace  ClassName::binaryStoreSize() const;
        Rwspace  ClassName::recursiveStoreSize() const;

メンバー関数は次の関数を使用します。

        RWFile& operator<<(RWFile& file, const ClassName&);

上記のメンバー関数は、クラス RWFileManager と RWBTreeOnDisk を使用してオブジェクトを記憶するのに適しています。RWCollectable から継承するオブジェクトの場合、2 つ目の別形 `recursiveStoreSize()` は、再帰的な記憶に使用されるバイト数を計算することができます。この別形は次の関数を使用します。

        RWFile& operator<<(RWFile& file, const RWCollectable&)

クラス RWAuditStreamBuffer を任意のストリームと組み合わせて使用して、バッファに渡されるバイト数をカウントできます。したがって、上記のメンバー関数がファイル用の機能を提供するように、このクラスはストリーム用の機能を提供します。クラス RWAuditStreamBuffer の詳細については、『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』を参照してください。

### ストリーム入出力

`ostream` オブジェクトを第 1 引数としてとる多重定義 (オーバーロード) された左シフト演算子 (`<<`) は、オブジェクトの内容を人が読める書式で出力します。一方、`istream` オブジェクトを第 1 引数としてとる多重定義された右シフト演算子 (`>>`) は、人が理解できる書式でストリームからオブジェクトを読み取り、構文解析します。

        ostream&  operator<<(ostream& ostr, const ClassName& x);
        istream&  operator>>(istream& istr, const ClassName& x);

多重定義された左シフトと右シフトの演算子は、対称的な持続演算子と考えられます。

      Rwvostream&  operator<<(RWvostream& vstream, const ClassName&);
      Rwvistream&  operator>>(RWvistream& vstream,       ClassName&);

持続シフト演算子は、ストリームとの間で格納と復元を行なうことができますが、必ずしも「人間が理解できる」形式でそうするとはかぎりません。

### 比較

ほとんどのクラスには次のような比較メンバー関数と等価メンバー関数があります。

      int        compareTo(ClassName*) const;
      RWBoolean  equalTo(ClassName*) const;

対応する論理演算子は次のようになります。

      RWBoolean  operator==(const ClassName&) const;
      RWBoolean  operator!=(const ClassName&) const;
      RWBoolean  operator<=(const ClassName&) const;
      RWBoolean  operator>=(const ClassName&) const;
      RWBoolean  operator<(const ClassName&) const;
      RWBoolean  operator>(const ClassName&) const;

## メモリーの割り当てと開放

オブジェクトがヒープから領域を割り当てられた場合、ライブラリによっては、所有権、つまりそれを削除する責任は誰にあるのかということが問題になります。

Rouge Wave クラスのほとんどは、非常に単純な方法をとります。ユーザーが何かにヒープ領域を割り当てた場合、それを開放するのはユーザーの責任になります。Rogue Wave ライブラリが何かにヒープ領域を割り当てた場合、それを開放するのは Rogue Wave ライブラリの責任になります。

オブジェクトの作成には 2 つの例外があります。最初の例外は次の演算子です。

      RWFile&      operator>>(RWFile& file, RWCollectable*&);
      Rwvistream&  operator>>(RWvistream& vstream, RWCollectable*&);

これらの演算子は、RWCollectable から継承したオブジェクトを、それぞれ RWFile または RWvistream から復元します。これらはヒープを割り当てられたオブジェクトへのポインタを返します。それを削除するのはユーザーの責任です。

第 2 の例外は次のメンバー関数です。

      RWCollection* RWCollection::select(RWtestCollectable,   void*)const;

これは、ヒープを割り当てられた、ある選択基準を満たすメンバーを持つコレクションへのポインタを返します。このコレクションを使用した後に削除するのもユーザーの責任です。

オブジェクト削除の例外もあります。サービスとして、コレクションクラスの多くはメソッド `clearAndDestroy()` を提供します。これは、コレクションからすべてのポインタを取り除いて、それぞれを削除します。ただし、`clearAndDestroy()` を使用する場合でも、コレクション内のポインタすべてを削除しても安全かどうかを確認するのはユーザーの責任です。

これらのメソッドの詳細は、『Tools.h++ 7.0 クラスライブラリ・リファレンスマニュアル』に記載されています。

## 情報の流れ

Rogue Wave ライブラリでは一般に、情報はその引数を通じて関数に入り、戻り値によって返されます。ほとんどの関数は引数を変更しません。実際、引数が次のように値として、つまり const 参照として渡される場合は、引数が変更されないことを確認することができます。

        void  foo(const RWCString& a)

しかし、引数が非 const 参照として渡された場合、関数がそれを変更する可能性があります。

引数がポインタとして渡される場合は、関数がそのポインタのコピーを保持する可能性が高くなります。これは、コレクションクラスの特徴を示すものです。

        RWOrdered::insert(RWCollectable*);

関数は、関数が返ってきた後で、コレクションがオブジェクトへのポインタを保持していることをユーザーに思い出させるために、ポインタのコピーを保持します。1

## マルチスレッド安全

コンパイラのリリースノートに従って適切なオプションによりコンパイルを行なうと、Tools.h++ はマルチスレッド安全になります。つまり、すべての Tools.h++ 関数は、マルチスレッド環境において、シングルスレッド環境と同様に働きます。もちろんこれは、アプリケーションプログラムがスレッド間での各オブジェクトの共有を避けるか、またはスレッド間で共有されるオブジェクトの操作に対してロックを実行することを前提としています。Tools.h++ には内部ロック機能があり、それ自身の保全性を維持して、適切なマルチスレッド安全システムコールを使用します。

## 8 ビットクリーン

Tools.h++ のすべてのクラスは 8 ビットクリーンです。つまり、ISO Latin-1 といった 8 ビットのコードセットを使用することができます。

## 埋め込まれたヌル

Tools.h++ のすべてのクラス (RWCString と RWWString を含む) は埋め込まれたヌルを持つ文字セットをサポートしています。これにより、複数バイトの文字セットを使用することができます。

## インデックス

インデックスの型は、コンパイラによって定義された符号なし整数型の `size_t` 型 (通常は `<stddef.h>` 内) です。符号なしであるため、16 ビットの `unsinged` を持つ 16 ビット MS-DOS と Windows では、64k -1 バイトまでインデックス付けすることができます。

無効なインデックスは `<rw/defs.h>` 内で定義された特別な値 `RW_NPOS` によって決まります。

## バージョン番号

プログラミングでは、特定の操作を実行するために、Tools.h++ の特定のバージョン番号が必要になる場合があります。この番号は、マクロ `RWTOOLS` で与えられ、16 進数で表現されます。たとえば、1.2.3 は 0x123 になります。これは、条件付きコンパイルに使用することができます。

実行時にバージョン番号が必要である場合は、ヘッダファイル `<rw/tooldefs.h>` に宣言された関数 `rwToolsVersion()` を使用して調べることができます。

#### 表 1-2 Tools.h++ クラスの公開クラス階層

これは公開クラス階層です。クラス実装は非公開継承を使用することもあります。複数の継承を持つクラスは、階層の両方の場所に示しています。それらのもう一方の基底はイタリック体で右側に示しています。

    RWBench
    RWBitVec
    RWBTreeOnDisk
    RWCacheManager
    RWCollectable
           RWCollection
                    RWBag
                    RWBinaryTree
                    RWBTree
                           RWBTreeDictionary
                    RWHashTable
                           RWSet
                                RWFactory
                                  RWHashDictionary
                                         RWIdentityDictionary
                                  RWIdentitySet
                    RWSequenceable
                           RWDlistCollectables
                           RWOrdered
                                  RWSortedVector
                           RWSlistCollectables
                                  RWSlistCollectablesQueue
                                  RWSlistCollectablesStack
           RWCollectableDate (&RWDate)
           RWCollectableInt (&RWInteger)
           RWCollectableString (&RWCString)
           RWCollectableTime (&RWTime)
           RWModelClient
    RWCRegexp
    RWCRExp
    RWCString
           RWCollectableString (&RWCollectable)
    RWCSubString
    RWCTokenizer
    RWDate
           RWCollectableDate (&RWCollectable)
    RWErrObject
    RWFile
           RWFileManager
    RWGBitVec(size)
    RWGDlist(type)
    RWGDlistIterator(type)
    RWGOrderedVector(val)
    RWGQueue(type)
    RWGSlist(type)
    RWGSlistIterator(type)
    RWGStack(type)
    RWGVector(val)
           RWGSortedVector(val)
    RWInteger
           RWCollectableInt (&RWCollectable)
    RWIterator
           RWBagIterator
           RWBinaryTreeIterator
           RWDlistCollectablesIterator
           RWHashDictionaryIterator
           RWHashTableIterator
                    RWSetIterator
           RWOrderedIterator
           RWSlistCollectablesIterator
    RWLocale
           RWLocaleSnapshot
    RWMessage
    RWModel
    RWTime
           RWCollectableTime (&RWCollectable)
    RWTimer
    RWTBitVec<size>
    RWTIsvDlist<T>
    RWTIsvDlistIterator<TL>
    RWTIsvSlist<T>
    RWTIsvSlistIterator<TL>
    RWTPtrDeque<T>
    RWTPtrDlist<T>
    RWTPtrDlistIterator<T>
    RWTPtrHashMap<Key,Type,Hash,EQ>
    RWTPtrHashMapIterator<Key,Type,Hash,EQ>
    RWTPtrHashMultiMap<Key,Type,Hash,EQ>
    RWTPtrHashMultiMapIterator<Key,Type,Hash,EQ>
    RWTPtrHashMultiSet<T,Hash,EQ>
    RWTPtrHashMultiSetIterator<T,Hash,EQ>
    RWTPtrHashSet<T,Hash,EQ>
    RWTPtrHashSetIterator<T,Hash,EQ>
    RWTPtrMap<Key,Type,Compare>
    RWTPtrMapIterator<Key,Type,Compare>
    RWTPtrMultiMap<Key,Type,Compare>
    RWTPtrMultiMapIterator<Key,Type,Compare>
    RWTPtrMultiSet<T,Compare>
    RWTPtrMultiSetIterator<T,Compare>
    RWTPtrOrderedVector<T>
    RWTPtrSet<T,Compare>
    RWTPtrSetIterator<T,Compare>
    RWTPtrSlist<T>
    RWTPtrSlistIterator<T>
    RWTPtrSlistDictionary<KeyP,ValP>
    RWTPtrSlistDictionaryIterator<KeyP,ValP>
    RWTPtrSortedDlist<T,Compare>
    RWTPtrSortedDlistIterator<T,Compare>
    RWTPtrSortedVector<T,Compare>
    RWTPtrVector<T>
    RWTQueue<T,Container>
    RWTRegularExpression<charT>
    RWTStack<T,Container>
    RWTValDeque<T>
    RWTValDlist<T>
    RWTValDlistIterator<T>
    RWTValHashMap<Key,Type,Hash,EQ>
    RWTValHashMapIterator<Key,Type,Hash,EQ>
    RWTValHashMultiMap<Key,Type,Hash,EQ>
    RWTValHashMultiMapIterator<Key,Type,Hash,EQ>
    RWTValHashMultiSet<T,Hash,EQ>
    RWTValHashMultiSetIterator<T,Hash,EQ>
    RWTValHashSet<T,Hash,EQ>
    RWTValHashSetIterator<T,Hash,EQ>
    RWTValMap<Key,Type,Compare>
    RWTValMapIterator<Key,Type,Compare>
    RWTValMultiMap<Key,Type,Compare>
    RWTValMultiMapIterator<Key,Type,Compare>
    RWTValMultiSet<T,Compare>
    RWTValMultiSetIterator<T,Compare>
    RWTValOrderedVector<T>
    RWTValSet<T,C>
    RWTValSetIterator<T,C>
    RWTValSlist<T>
    RWTValSlistIterator<T>
    RWTValSlistDictionary<Key,V>
    RWTValSlistDictionaryIterator<Key,V>
    RWTValSortedDlist<T,Compare>
    RWTValSortedDlistIterator<T,Compare>
    RWTValSortedVector<T>
    RWTValVector<T>
    RWTValVirtualArray<T>
    RWvios
           RWios (virtual)
                    RWvistream
                           RWbistream  (&ios: virtual)
                                  RWeistream
                           RWpistream
                             RWXDRistream  (&RWios)
                    RWvostream
                           RWbostream  (&ios: virtual)
                                  RWeostream
                             RWpostream
                             RWXDRostream  (&RWios)
    RWVirtualPageHeap
           RWBufferedPageHeap
                    RWDiskPageHeap
    RWWString
    RWWSubString
    RWWTokenizer
    RWZone
           RWZoneSimple
    streambuf
           RWAuditStreamBuffer
           RWCLIPstreambuf
                    RWDDEstreambuf
    xmsg
           RWxmsg
                    RWExternalErr
                           RWFileErr
                           RWStreamErr
                    RWInternalErr
                           RWBoundsErr
                    RWxalloc

1 別の設計方針として、コレクションに挿入しようとするオブジェクトを参照によって渡す (NIH クラスで行われるように) というやり方もあったわけですが、我々はこの方法を 2 つの理由から避けました。つまり、"値による受け渡し" と似すぎていること (そのためプログラマが、保持した参照を簡単に忘れてしまう) と、スタックに保存される変数への参照を格納するのが簡単になりすぎるということです。