前のページ次のページ上に戻るホーム SophiaFramework 2.2

5.4. マップ

5.4.1. マップ クラス

マップは、キーを値に対応付けるコレクションです。

図 5.4. マップ クラス

マップ クラス

SFUMap は抽象クラスで、 マップとして実装すべきインターフェイスを定義します。

表 5.4. SFUMap の抽象仮想関数

Put キーと値の対応付けを登録します。
Remove キーに対応するエントリを削除します。
Get キーに対応する値を取得します。
GetSets キーと値を列挙するイテレータを返します。
GetKeys キーを列挙するイテレータを返します。
GetValues 値を列挙するイテレータを返します。

マップを実装した具象クラスにはハッシュ マップ SFUHashMap があります。 ハッシュ マップはハッシュにより実装されたマップです。

5.4.2. マップの使用例

次の例では、ハッシュ マップとイテレータの使い方を示しています。

// ハッシュ マップに格納するデータ型を定義
struct Address {
    ACharPtr zip;
    ACharPtr state;
    ACharPtr city;
    Address(ACharPtr zip, ACharPtr state, ACharPtr city) 
        : zip(zip), state(state), city(city) {}
};
Address* pAddr;

// ハッシュ マップを構築
SFUHashMap map;

pAddr = new Address("505-8856", "Tokyo", "Chiyoda-ku");
map.Put("Yamada", pAddr);
pAddr = new Address("808-6993", "Kyoto", "Kyoto-shi");
map.Put("Suzuki", pAddr);
pAddr = new Address("121-2232", "Hokkaido", "Sapporo-shi");
map.Put("Satou", pAddr);

// ハッシュ マップのキーの列挙
TRACE("HashMap count = %d", map.GetSize());
SFUConstIterator it = map.GetKeys();
for ( ;  ! it.End(); it++ ) {
    ACharPtr name = (ACharPtr) it.Get();   
    pAddr = (Address*) map.Get(name);
    TRACE("name = %s, state = %s", name, pAddr->state);
}

// ハッシュ マップのキーと値を同時に列挙
it = map.GetSets();
for ( ;  ! it.End(); it++ ) {
    SFUMap::Node* node = (SFUMap::Node*) it.Get();
    ACharPtr name = (ACharPtr) node->key;
    pAddr = (Address*) node->data;
    TRACE("name = %s, state = %s", name, pAddr->state);
}

// ハッシュ マップ内の値の解放
it = map.GetValues();
for ( ; ! it.End(); it++ ) {
    pAddr = (Address*) it.Get();
    delete pAddr;
}

最初にハッシュ マップを構築してデータを登録しています。 コレクションに登録できる要素はポインタだけですので、 ヒープにデータを作成して登録しています。

コレクション内の要素を列挙するには、イテレータを使います。 ここでは GetKeys() によってキーを列挙するイテレータを取得した後、 そのキーに対応するデータを取得しています。 また、++ 演算子で進めながら次々に要素を取得しています。 イテレータが列挙を完了したかどうかは、End() 関数により判定できます。

キーと値を同時に列挙することも可能です。 そのためには GetSets() 関数によってキーと値のペアを列挙するイテレータを取得します。 キーと値のペアは SFUMap::Node 型により表現されますので、 イテレータの Get() の戻り値を、この型のポインタにキャストします。 この型は key と data の 2 つのメンバ変数をもちますので、 これにアクセスすることでキーと値を同時に取得できます。

コレクションに登録されたポインタは、 コレクション オブジェクトが破棄されても解放されるわけではありません。 そのため、ヒープ ポインタを明示的に解放する必要があります。 これを行わないとメモリ リークが発生しますので注意してください。