株式会社エス・スリー・フォー

[Tools++.h]10.3 コレクション内のオブジェクトの取り出し

コレクションクラスの主な目的は、オブジェクトの格納と取り出しであると、以前に定義しました。オブジェクトをどのように取り出すまたは検索するかは、オブジェクトのプロパティにより異なります。作成された各オブジェクトは、それに関連付けられた 3 つのプロパティを持ちます。

  1. : 例えば RWCStringdouble など。C++ では、オブジェクトの型は作成時に設定され、変更できません。

  2. 状態: 文字列の値。インスタンス変数やオブジェクトの属性すべての値がそのオブジェクトの状態を決定します。これらは変更できます。

  3. アイデンティティ: 常にオブジェクトを一意に定義するもの。オブジェクトのアイデンティティの確立には、言語により異なる方法が使用されます。C++ では、常にオブジェクトのアドレスが使用されます。各オブジェクトは一対一で 1 つのアドレスに関連付けられます。ただし、継承を行うと、その逆は必ずしも真ではないことに注意してください。一般に、継承階層内で特定のオブジェクトを指すには、アドレスと型[1]
    の両方が必要です。

10.3.1 取り出し方法

オブジェクトのプロパティをもとにして、オブジェクトを検索または読み出すには、一般的に 2 つの方法があります。コレクションクラスの中には、以下のどちらにも対応しているものもあれば、どちらか 1 つにだけ対応しているものもあります。どちらを使っているのかを、常に念頭に入れておくことが大切です。その 2 つの方法は、以下のとおりです。

  1. ある特定の状態のオブジェクトを見つけます。例えば、2 つの文字列が同じ値を持つかどうかを調べる場合です。他のマニュアルでは、調べる 2 つのオブジェクトが「isEqual である」、「等値である」、「compares equal である」、「同じ値を持つ」、あるいは「== 演算子が真である」などと表現されています。ここでは、等値である 2 つのオブジェクトを isEqual であると言うことにします。一般に、等値性を調べるのに適切なインスタンス変数を見つけるには、各オブジェクトの型、あるいは継承している場合には派生型を知っている必要があります。[2]

  2. ある特定のオブジェクト、すなわち比較するオブジェクトと同じアイデンティティを持つオブジェクトを見つけます。他のマニュアルでは、調べる 2 つのオブジェクトが「isSame である」、「同じアイデンティティを持つ」、または「== 演算子が真である」と表現されています。ここでは 2 つのオブジェクトが「同じアイデンティティを持つ」と言うことにします。値ベースのコレクションクラスでは、格納するオブジェクトのコピーを作成するため、値ベースのコレクションクラス内で、ある特定のアイデンティティを持つオブジェクトを探すことは意味がないことに注意してください。

C++ では、アイデンティティを調べる (つまり、2 個のオブジェクトが同じオブジェクトかどうかを調べる) には、オブジェクトが同一のアドレスを持つかどうかを調べなければなりません。多重継承を行う場合があるため、基底クラスのアドレスとその派生クラスのアドレスは必ずしも同じではありません。このため、2 つのポインタ (アドレス) を比較してアイデンティティを調べる場合、2 つのポインタの型は同じでなければなりません。

Smalltalk では、= 演算子を使って等値性を、== 演算子を使ってアイデンティティを調べます。一方、C++ では、= 演算子は代入の意味に、== 演算子は値の等値性に強く結び付けられています。Rogue Wave では C++ のアプローチを採用しています。Rogue Wave では C++ のアプローチを採用しており、一般に == 演算子が 2 つのクラスに適用された場合は、値の等値性 (isEqual) を調べることを意味し、2 つのポインタに適用された場合はアイデンティティを調べることを意味します。

等値性またはアイデンティティのどちらを調べるかは、文脈によって変わります。どちらを選択すべきかを明確にするために、例をいくつか示します。

等値性を調べるべき場合の例を示します。宛先リストを管理しているとします。名前を与えて、その人の住所を検索するようにしたいとしましょう。この場合、与えた名前と等しい名前を検索するので、RWHashDictionary が適切だといえます。 辞書のキーは名前で、値が住所になります。

次の例では、アイデンティティを調べます。ハイパーテキストアプリケーションを作成していて、ある特定のグラフィックがどのドキュメントで表示されるかを知る必要があるとします。グラフィックとそれに対応するドキュメントの RWHashDictionary を持つことが可能です。ただし、この場合、ある特定のグラフィックがどのドキュメントで表示されるかを知る必要があるので、RWIdentityDictionary が必要です。グラフィックをキーとして、ドキュメントを値とします。

特定のオブジェクトがメモリに常駐しているかどうかを知っておくといいでしょう。この場合は、RWIdentitySet が適当です。オブジェクトを与えて、それがメモリに存在するかどうかを調べることができます。これは、アイデンティティを調べるもう一つの方法です。

注釈

  1. ^ 特定のオブジェクトを指すためには、多重継承を行っている場合、オブジェクトの型だけでなく、継承ツリー内の位置も必要になる場合があります。
  2. ^ Rogue Wave コレクションクラスでは、一般化された等価のテストが行えます。つまり、2 つのオブジェクトが「等しい」とはどのような意味かを、ユーザが定義することができます。2 個のオブジェクトのビット単位での比較は行われません。例えば、文脈次第では、パンダと鹿の両方とも哺乳動物なので、パンダは鹿と同等であると定義することもできます。