(57)【特許請求の範囲】
【請求項１】
ＣＰＵが、メモリに事前に格納されたプログラムの命令に基づいて、囲んでいるオブジェクトにインターフェイスを追加するための、ＣＰＵ及びメモリを有するコンピュータシステムにおいて実行される方法であって、オブジェクトにより実現されるインターフェイスが、囲んでいるオブジェクト内に囲まれ得るようにし、当該囲まれ得るオブジェクトが、上記インターフェイスに対する参照を検索するための問い合わせ関数メンバを有し、当該囲んでいるオブジェクトが、当該囲んでいるオブジェクトにインターフェイスを追加するためのインターフェイス追加関数メンバ、及び、追加されたインターフェイスに対する参照を検索するための問い合わせ関数メンバを有し、当該囲まれ得るオブジェクトがクラスによって規定され、当該囲んでいるオブジェクトがクラスによって規定されるものであり、以下の各段階、即ち、
ＣＰＵが、メモリ内に事前に記憶されたプログラム命令に基づいて、上記囲んでいるオブジェクトを規定するクラスのインスタンスを形成することによって、メモリ内に、上記囲んでいるオブジェクトを形成し、
ＣＰＵが、メモリ内に事前に記憶されたプログラム命令に基づいて、囲まれ得るオブジェクトを規定するクラスのインスタンスを形成することによって、上記囲んでいるオブジェクト内に囲まれ得るオブジェクトをメモリ内に形成し、ＣＰＵが、上記囲んでいるオブジェクトのオブジェクト管理インタフェースに対する参照を囲まれ得るオブジェクトに渡し、そして
ＣＰＵが、上記囲んでいるオブジェクトのインターフェイス追加関数メンバを呼び出し、囲まれ得るオブジェクトのインタフェースに対する参照を上記インターフェイス追加関数メンバに渡してオブジェクトを囲むと、その囲まれたオブジェクトのインターフェイスが上記囲んでいるオブジェクトに追加され、これにより集合オブジェクトを形成し、上記囲んでいるオブジェクトの問合せ関数メンバが上記集合オブジェクト以外の他のオブジェクトによって呼び出されたときに、上記囲んでいるオブジェクトの問合せ関数メンバは、上記囲んでいるオブジェクトに追加されたインターフェイスに対する参照を上記他のオブジェクトに返送する、
という段階を備えたことを特徴とする方法。
【請求項２】
ＣＰＵは、上記囲んでいるオブジェクトの問合せ関数メンバが呼び出された後、上記囲んでいるオブジェクトに追加されたインターフェイスに対する参照を上記他のオブジェクトに返送するにあたり、当該問い合わせ関数メンバからの応答を待たないことにより、上記囲んでいるオブジェクトの問合せ関数メンバの呼び出しを、非同期で行う請求項１に記載の方法。
【請求項３】
ＣＰＵは、上記囲んでいるオブジェクトの問合せ関数メンバが呼び出された後、上記囲んでいるオブジェクトに追加されたインターフェイスに対する参照を上記他のオブジェクトに返送するにあたり、当該問い合わせ関数メンバからの応答を待つことにより、上記囲んでいるオブジェクトの問合せ関数メンバの呼び出しを同期して行う請求項１に記載の方法。
【請求項４】
上記囲んでいるオブジェクトは、デフォールト動作を実現するインターフェイスを与える請求項１に記載の方法。
【請求項５】
上記囲んでいるオブジェクトは、囲まれたオブジェクトの追加されたインターフェイスをオーバーライドするインターフェイスを与える請求項１に記載の方法。
【請求項６】
上記囲んでいるオブジェクトは、囲まれたオブジェクトによって提示されるインターフェイスについての知識をもたない請求項１に記載の方法。
【請求項７】
上記コンピュータシステムは、永続記憶のための装置を有し、そして更に、
囲まれ得るオブジェクトのインタフェースに対する参照を、囲んでいるオブジェクトに渡した後に、それによって集合オブジェクトを形成し、また、ＣＰＵによりその集合オブジェクトを上記永続記憶装置に記憶し、
ＣＰＵは、上記集合オブジェクトを記憶した後に、その記憶された集合オブジェクトを上記永続記憶装置からその後にロードするという段階を備えた請求項１に記載の方法。
【請求項８】
ＣＰＵは、上記囲んでいるオブジェクトのインターフェイス追加関数メンバを呼び出した後、メモリ内に記憶されたプログラム命令に基づいて、上記囲んでいるオブジェクトの中に囲まれ得る第２のオブジェクトをメモリ内に形成し、これにより、ＣＰＵは上記囲んでいるオブジェクトのオブジェクト管理インタフェースに対する参照を上記第２のオブジェクトに渡し、第２のオブジェクトは提示されたインターフェイスを有し、そして、
ＣＰＵは、上記囲んでいるオブジェクトのインターフェイス追加関数メンバを２回目に呼び出すと、上記第２オブジェクトの提示されたインターフェイスを上記囲んでいるオブジェクトに追加することにより上記第２オブジェクトを囲むと、これにより、ＣＰＵは、囲まれた第１オブジェクトの問合せ関数メンバが上記集合オブジェクト以外の他のオブジェクトによって呼び出されたときに、上記囲まれた第１オブジェクトの問合せ関数メンバが上記囲まれた第２オブジェクトの追加され提示されたインターフェイスに対する参照を上記他のオブジェクトに返送する、
という段階を更に備えた請求項１に記載の方法。
【請求項９】
上記囲まれた第２オブジェクトの提示されたインターフェイスは、上記囲まれた第１オブジェクトのインターフェイスをオーバーライドする請求項８に記載の方法。
【請求項１０】
ＣＰＵが、上記囲まれた第２オブジェクトの提示されたインターフェイスを用いて、上記囲まれた第１オブジェクトのインターフェイスを呼び出す請求項８に記載の方法。
【請求項１１】
上記囲まれた第２オブジェクトの提示されたインターフェイスは、デフォールト動作を実現するインターフェイスである請求項８に記載の方法。
【請求項１２】
上記囲まれた第１オブジェクトは、上記囲んでいるオブジェクトのインタフェースに対する参照を含み、上記第２オブジェクトは、第２オブジェクトの提示されたインターフェイスに対する参照を検索するための問合せ関数メンバを有し、そして更に、ＣＰＵが、囲んでいるオブジェクトのインタフェース追加関数メンバを２回目に呼び出した後に、ＣＰＵは、以下の段階、即ち、
第１に、２回目に、囲んでいるオブジェクトのインターフェイス追加関数メンバを呼び出した後に、上記囲まれた第１オブジェクトの問合せ関数メンバを呼び出すことによって第２オブジェクトの提示されたインターフェイスを要求し、
第２に、上記囲まれた第１オブジェクトに含まれている上記囲んでいるオブジェクトのインタフェースに対する参照を介して、上記囲んでいるオブジェクトの問合せ関数メンバに対する参照を検索し、
第３に、上記囲んでいるオブジェクトの問合せ関数メンバを呼び出し中に、上記要求されたインターフェイスを囲んでいるオブジェクトの問合せ関数メンバに渡し、
第４に、上記囲んでいるオブジェクトの問合せ関数メンバから、上記囲まれた第２オブジェクトの問合せ関数メンバを呼び出し中に、上記要求されたインターフェイスを上記囲まれた第２のオブジェクトの問合せ関数メンバに渡し、そして
第５に、上記要求されたインターフェイスに対する参照を、上記囲まれた第２オブジェクトの問合せ関数メンバから上記囲んでいるオブジェクトの問合わせ関数メンバに返送する、
という段階を更に備えた請求項８に記載の方法。
【請求項１３】
上記囲んでいるオブジェクトは、どの追加インターフェイスに対する参照を検索するかを決定するためのルールを追加するルール追加関数メンバを有し、そして更に、囲んでいるオブジェクトに、囲まれ得るオブジェクトに対する参照を渡した後に、それによって集合オブジェクトを形成し、さらにどの追加インターフェイスに対する参照を検索するかを決定するルールを追加するために、ＣＰＵは上記囲んでいるオブジェクトのルール追加関数メンバを呼び出し、これにより、ＣＰＵは、上記囲んでいるオブジェクトの問合せ関数メンバを呼び出したとき、その問合せ関数メンバを実行することに基づいて、その追加されたルールからどの追加インターフェイスに参照を返送するかを決定するという段階を更に備えた請求項８に記載の方法。
【請求項１４】
上記コンピュータシステムにおいて実行される方法を実現するための各処理は、特定のオブジェクト指向言語に限定されずに実行できる、請求項８に記載の方法。
【請求項１５】
ＣＰＵは、囲んでいるオブジェクトのルール追加関数メンバを呼び出した後に、要求されたインターフェイスに対する参照を検索するために上記囲んでいるオブジェクトの問合せ関数メンバを呼び出し、これにより、上記囲んでいるオブジェクトの問合せ関数メンバの実行に基づいて、追加されたルールを用いて、どのインターフェイスに参照を返送するかを決定するという段階を更に備えた請求項１３に記載の方法。
【請求項１６】
オブジェクトにインターフェイスを追加するためのコンピュータシステムにおいて、
ＣＰＵと、
ＣＰＵのためのメモリと、
ＣＰＵにより、囲んでいるオブジェクトへのインターフェイスを追加するためのインターフェイス追加関数メンバ、及び、インターフェイスに対する参照を検索するための問合せ関数メンバを有する、メモリ内の囲んでいるオブジェクトと、
上記囲んでいるオブジェクト内に囲まれ得るオブジェクトとを備え、
上記囲まれ得るオブジェクトは、インターフェイスと、該インターフェイスに対する参照を上記ＣＰＵにより検索するための問合せ関数メンバとを有し、
ＣＰＵが、上記囲んでいるオブジェクトのインターフェイス追加関数メンバを呼び出し、囲まれ得るオブジェクトのインターフェースに対する参照を上記インターフェイス追加関数メンバに渡してオブジェクトを囲むと、その囲まれたオブジェクトのインターフェイスが上記囲んでいるオブジェクトに追加され、これにより集合オブジェクトを形成すると、上記囲んでいるオブジェクトの問合せ関数メンバが上記集合オブジェクト以外の他のオブジェクトによって呼び出されたときに、上記囲んでいるオブジェクトの問合せ関数メンバは、上記囲んでいるオブジェクトに追加されたインターフェイスに対する参照を上記他のオブジェクトに返送することを特徴とするコンピュータシステム。
【発明の詳細な説明】
【０００１】
【クロスレファレンス】
本発明は、参考としてここに取り上げる１９９２年１２月２４日出願の「オブジェクトの集合方法及びシステム(A Method and System for Aggregating Objects) 」と題する米国特許出願第０７／９９６，５５２号の一部継続出願である。
【０００２】
【産業上の利用分野】
本発明は、一般に、コンピュータにおいてオブジェクトに対してインターフェイスを実行する方法及びシステムに係、より詳細には、オブジェクトを集合させる方法及びシステムに係る。
【０００３】
【従来の技術】
コンピュータソフトウェアシステムが複雑になるにつれ、ソフトウェアを開発するためのコストも増加している。ソフトウェア開発コストを最小限にするために、開発者は、コードを共用することが多い。従来の開発技術では、３つのタイプのコード共用を使用している。すなわち、（１）ソースコードの共用、（２）コンパイル済コードの共用、（３）継承によるコード共用、である。
【０００４】
又、コンピュータソフトウェアシステムが複雑になるにつれ、ソフトウェアのユーザは、コンピュータシステムの保守及び拡張が益々複雑になることに直面している。ソフトウェアの販売者が新たな又は改良した能力を形成するたびに、その特典を得ようとするユーザは、それらの変更をともかく組み込まねばならない。公知のシステムは、一般に、このようなユーザがソフトウェアをグレードアップする必要があり、ユーザは、システムの少なくとも一部分を再設置することを余儀なくされる。或いは、公知システムは、ソフトウェアの開発者が将来の増強を前もって計画し、そしてオリジナルのシステムに必要なフックを設置して、将来に増強手段を装填できるようにする必要がある。
【０００５】
更に、ユーザが、異なるソフトウェア販売者によって発売された能力を付加することにより現在所有しているソフトウェアの一部分の能力を増強しようとする場合には、ソフトウェア販売者が前もって計画しているものによりユーザに制限が課せられる。公知のシステムは、一般に、ソフトウェアの２つの部片が一緒に機能するように設計されると共に、これらソフトウェア部片の少なくとも一方がその他方により与えられる能力を知ることが必要とされる。従って、公知のシステムでは、コードに対するその後の変更及びコードの共用を、ソフトウェア設計に考慮しておかねばならない。
【０００６】
ソースコードおよびコンパイル済コードを共用する方法は、長年広く使用されてきた。ソースコードの共用とは、さまざまなコンピュータプログラム又は同一のコンピュータプログラムのさまざまなバージョンで同一のコードを使用することである。例えば、一般にスプレッドシートプログラムは、スップレッドシート表示を制御するソースコードを含む。ワードプロセッシングプログラムでスプレッドシートを文書内に埋め込むことができれば、そのワードプロセッシングプログラムは同一の（又はわずかに修正した）ソースコードを使用して、埋め込んだスプレッドシートオブジェクトを表示することができる。ソースコードは、一般に単独の開発者が複数のコンピュータプログラムを開発する際に共用される。他者と競争する関係上、開発者は他の開発者とコードを共用しない。さらに、コードを共用する場合でさえ、ソースコード受信者はソースコードを修正するのが一般的であり、この結果、ソースコードに対し２つのバージョンが維持されることになる。
【０００７】
コンパイル済コードの共用とは、さまざまなコンピュータプログラムで同一のコンパイル済コードを使用することである。一般に、コンパイル済コードは静的リンクライブラリまたは動的リンクライブラリに格納される。静的リンクライブラリに格納されたコードは、実行前にコンピュータプログラムを連係した場合に共用される。例えば、スペルチェックプログラムの開発者は、そのプログラムをコンパイルして静的リンクライブラリにコンパイル済コードを格納することによってコンパイル済コードを共用できる。その後、静的リンクライブラリをワードプロセッシングプログラム開発者に配布することによって、これらの開発者はコンパイル済スペルチェックコードをそれぞれのワードプロセッシングプログラムに連係することができる。一般に、スペルチェックプログラム開発者は、コンパイル済コード修正して、特定開発者の特殊な要求に応じなければならない。こうした修正によって、コンパイル済コードの複雑化（とサイズの増大）を助長するだけでなく、他の受信者の要求と矛盾する可能性もある。他に、開発者が、静的リンクライブラリの複数のバージョンを分散することも考えられる。しかし複数のバージョンを保守するにはコストがかかりかねない。
【０００８】
オブジェクト指向のプログラミング技術は、コードを共用できるようにする継承と称する概念を使用している。本発明は、オブジェクト指向のプログラミングを用いて以下に説明するので、良く知られたオブジェクト指向のプログラミング技術を要約する。オブジェクト指向プログラミング言語では、データのカプセル化とデータタイプの継承を支援するという２つの特徴が一般に知られている。データのカプセル化とは、関数とデータを結合させることである。継承は、あるデータタイプを別のデータタイプに関して宣言する能力を指す。
【０００９】
Ｃ＋＋言語では、オブジェクト指向言語はクラスを使用して支援される。クラスは、ユーザが定義したタイプである。クラスの宣言によって、クラスのデータメンバとメンバ関数が定義される。例えば、下記の宣言はCIRCLEというクラスのデータメンバとメンバ関数とを定義する。
0004322967.tif 000002
変数ｘおよびｙは、円の中心座標を指定し、変数radiusはその円の半径を指定する。これらの変数をクラスCIRCLEのデータメンバという。関数drawは、ユーザが定義した関数で、指定座標から指定した半径で円を描く。この関数drawをクラスCIRCLEの関数メンバという。あるクラスのデータメンバと関数メンバは、関数がクラスのインスタンスで動作するという点で一緒に結合される。クラスのインスタンスは、クラスのオブジェクトとも呼ばれる。
【００１０】
Ｃ＋＋の構文では、下記のステートメントは、オブジェクトａ及びｂがタイプクラスCIRCLEであることを宣言する。
CIRCLE a, b;
この宣言は、オブジェクトａ及びｂにメモリを割り当てる。下記のステートメントは、オブジェクトａ及びｂのデータメンバにデータを割り当てる。
a. x      =2;
a. y      =2;
a. radius =1;
b. x      =4;
b. y      =5;
b. radius =2;
下記のステートメントは、オブジェクトａ及びｂによって定義される円を描くのに用いられる。
a. draw();
b. draw();
【００１１】
導出クラスは、その基本クラスの特性、すなわちデータメンバと関数メンバを継承するクラスである。例えば、下記の導出クラスCIRCLE FILLは、基本クラスCIRCLEの特徴を継承する。
0004322967.tif 000003
この宣言は、クラスCIRCLE FILLが、クラスCIRCLE FILLの宣言時に導入したデータメンバ及び関数メンバ、即ちデータメンバ pattern及び関数メンバfillに加えて、クラスCIRCLEに存在する全てのデータメンバ及び関数メンバを含むことを指定する。この例では、クラスCIRCLE FILLは、データメンバｘ、ｙ、radius、及びpattern と、関数メンバdraw及びfillとを有している。クラスCIRCLE FILLは、クラスCIRCLEの特徴を「継承する」と言える。他のクラスの特徴を継承するクラスは、導出クラス（CIRCLE FILLなど）である。他のクラスの特徴を継承しないクラスを一次クラス（ルートクラス）という（CIRCLEなど）。他クラスによって特徴が継承されるクラスは、基本クラスである（例えば、CIRCLEは、CIRCLE FILLの基本クラスである）。導出クラスは、複数のクラス特徴を継承することができる。つまり、導出クラスは複数の基本クラスを有することができる。これを多重継承という。
【００１２】
導出クラスは、基本クラスが仮想的に継承されることを指定してもよい。基本クラスの仮想継承とは、仮想基本クラスのインスタンスが導出クラス中の１つしか存在しないことを意味する。例えば、下記は非仮想基本クラスを有する導出クラスの１例である。
class CIRCLE 1 : CIRCLE  ｛... ｝;
class CIRCLE 2 : CIRCLE  ｛... ｝;
class PATTERN   : CIRCLE 1,  CIRCLE 2 ｛... ｝;
この宣言では、クラスPATTERN は、クラスCIRCLE 1 及びCIRCLE 2 によりクラスCIRCLEを非仮想的に２度継承する。つまり、クラスPATTERN にはクラスCIRCLEのインスタンスが２つ存在するのである。
【００１３】
下記は、２つの仮想基本クラスを有する導出クラスの１例である。
class CIRCLE 1 : virtual CIRCLE  ｛... ｝;
class CIRCLE 2 : virtual CIRCLE  ｛... ｝;
class PATTERN   : CIRCLE 1,  CIRCLE 2 ｛... ｝;
導出クラスPATTERN は、クラスCIRCLE 1 及びCIRCLE 2 によりクラスCIRCLEを仮想的に２度継承する。クラスCIRCLEは、２度仮想的に継承されるので、導出クラスPATTERN には、クラスCIRCLEのオブジェクトが１つしか存在しないことになる。クラス導出が複雑な場合に、仮想継承が非常に有益であることが当業者に明らかであろう。
【００１４】
クラスは、その関数メンバが仮想的であるかどうかも指定できる。ある関数メンバが仮想的であると宣言することは、その関数が導出クラスにおいて同一名及び同一タイプの関数によってオーバーライドできることを意味する。下記の例では、関数drawをクラスCIRCLEとCIRCLE FILLで仮想的であると宣言している。
0004322967.tif 000004
仮想関数が、実現を与えずに宣言される場合には、純粋な仮想関数と称される。純粋な仮想関数は、純粋な指定子"=0"で宣言された仮想関数である。あるクラスが純粋な仮想関数を指定する場合には、いかなる導出クラスも、その関数メンバが呼び出される前に、その関数メンバに対する実現を指定する必要がある。
【００１５】
オブジェクトをアクセスするために、Ｃ＋＋言語は、ポインタデータタイプを与える。ポインタは、メモリ中のオブジェクトのアドレスである値を保持する。ポインタにより、オブジェクトに参照することができる。下記のステートメントは、変数 c ptr がタイプクラスCIRCLEのオブジェクトのポインタであることを宣言し、そしてオブジェクトｃのアドレスを保持するように変数 c ptr をセットする。
CIRCLE *c ptr
c ptr = &c;
この例に続き、下記のステートメントは、オブジェクトａがタイプクラスCIRCLEであり、オブジェクトｂがタイプクラスCIRCLE FILLであることを宣言する。
CIRCLE  a ;
CIRCLE FILL b;
下記のステートメントは、クラスCIRCLEで定めたように関数drawを参照する。
a. draw() ;
一方、下記のステートメントは、クラスCIRCLE FILLで定義した関数drawを参照する。
b. draw() ;
更に、下記のステートメントは、キャストオブジェクトｂをタイプクラスCIRCLEのオブジェクトにタイプ決めし、クラスCIRCLE FILLで定義した関数drawを呼び出す。
CIRCLE *c ptr;
c ptr = &b;
c ptr->draw() ;    //   CIRCLE FILL :: draw()
従って、呼び出される仮想関数は、関数CIRCLE FILL::drawである。
【００１６】
図１は、オブジェクトの表現に使用する一般的なデータ構造を示すブロック図である。オブジェクトはインスタンスデータ（データメンバ）およびメンバ関数であり、オブジェクトを実際に動作させる。オブジェクトの表現に使用するデータ構造は、インスタンスデータ構造１０１と、仮想関数表１０２と、関数メンバ１０３、１０４及び１０５から成る。インスタンスデータ構造１０１は、仮想関数表１０２に対するポインタとデータメンバを含む。仮想関数表１０２は、オブジェクトに対して定義した各仮想関数メンバのエントリを含む。各エントリは、対応する関数メンバを実行するコードの参照を含む。このサンプルオブジェクトのレイアウトは、参考としてここに取り上げる米国特許出願第07／682,537 号「A Methodfor Implementing Virtual Function and Virtual Bases in a Compiler for an Object Oriented Programming Language 」に適合する。以下の説明において、オブジェクトを、Ｃ＋＋プログラミング言語で定義したクラスのインスタンスとして述べる。当業者は、オブジェクトは他のプログラミング言語を使用して定義できることが明らかであろう。
【００１７】
クラスの継承は、コード共用の１形式である。クラス開発者は、他の開発者にクラスの実現体を提供することができる。この他の開発者は、提供されたクラスから導出するクラスを作成することができる。ただし、クラスが継承されて、仮想関数がオーバーライドされる場合は、オーバーライド仮想関数のテストは複雑になることが考えられる。オーバーライド仮想関数は、非オーバーライド関数に影響を与えるようにオブジェクトの状態を修正することができる。このため、各継承関数は、オーバーライド仮想関数のテストに関連して独立したテストをする必要がある。テストの複雑さを改善するには、クラスの実現体の開発者は、その実現体をもつソースコードを分配することができる。不幸にも、ソースコードの分配は、上述のように、共用ソースコードに同様の支障が生じる。
【００１８】
オブジェクト指向技術の利点は、オブジェクトの共用を容易にできることである。特に、オブジェクト指向技術は複合文書の作成を容易にする。複合文書は、さまざまなコンピュータプログラムによって生成されたオブジェクトを含む文書である。（一般に、オブジェクトのデータメンバとクラスタイプのみが複合文書に格納される。）例えば、スプレッドシートプログラムで生成したスプレッドシートオブジェクトを含むワードプロセッシング文書は、複合文書である。ワードプロセッシングプログラムでは、ユーザは（セルなど）スプレッドシートをワードプロセッシング文書内に埋め込むことができる。この埋め込みは、ワードプロセッシングプログラムを、埋め込むべきオブジェクトのクラス定義を使用して埋め込んだオブジェクトの関数メンバにアクセスして、コンパイルすることによって可能となる。このため、ワードプロセッシングプログラムは、ワードプロセッシング文書に埋め込むことができるオブジェクトの各クラスのクラス定義を使用してコンパイルしなければならない。新しいクラスのオブジェクトをワードプロセッシング文書に埋め込むには、ワードプロセッシングプログラムは新たなクラス定義でリコンパイルしなければならないと考えられる。このため、ワードプロセッシングプログラムの開発者が選択したクラスオブジェクトだけを埋め込むことができる。さらに、新たなクラスをワードプロセッシングプログラムを新たにリリースしてのみ支援することができる。
【００１９】
任意クラスのオブジェクトを複合文書に埋め込むには、ワードプロセッシングプログラムがコンパイル時間にクラス定義にアクセスする必要なしにオブジェクトをアクセスできるようにインタフェースを定義する。抽象クラスは、実現部をもたない仮想関数メンバ（純粋な仮想関数メンバ）が少なくとも１つは存在するクラスである。インタフェースは、データメンバがない抽象クラスであり、その仮想関数はすべて純粋である。従って、インターフェイスは、２つのプログラムがコミニケーションすべきプロトコルを与える。インターフェイスは、一般に、導出に対して使用され、プログラムは、クラスが導出されるインターフェイスに対して実現部を与えるようなクラスを実現する。その後に、これら導出されたクラスのインスタンスとしてオブジェクトが形成される。
【００２０】
以下のクラス定義は、インタフェースの定義の一例である。この例では、説明を簡略にするために、オブジェクトのクラスを文書に埋め込めるようにするのではなく、ワードプロセッシングプログラムは、スプレッドシートオブジェクトを埋め込めるようにする。オブジェクトがどのように実現されるかに係わりなく、このインタフェースを与えるスプレッドシートオブジェクトを埋め込むことができる。更に、スプレッドシートオブジェクトは、ワードプロセッシングプログラムをコンパイルする前に実現されるかその後に実現されるかに係わりなく、埋め込むことができる。
0004322967.tif 000005
スプヘレッドシートプログラムの開発者は、スプレッドシートオブジェクトをワードプロセッシング文書に埋め込むことができるように、インタフェースの実現を与える必要がある。
【００２１】
ワードプロセッシングプログラムがスプレッドシートオブジェクトを埋め込むときは、そのプログラムは、スプレッドシートオブジェクトに対するインタフェースを実現するコードにアクセスしなければならない。そのクラスコードにアクセスするために、各実現部には独特のクラス識別子が与えられる。例えば、マイクトソフト社が開発したスプレッドシートオブジェクトは、「MSSpreadsheet 」というクラス識別子を有するが、他社開発のスプレッドシートオブジェクトを実施するコードは、「LTSSpreadsheet」というクラス識別子を有する。各コンピュータシステムには永続登録が維持され、これは、各クラス識別子を、クラスを実現するコードにマップする。一般に、スプレッドシートプログラムがコンピュータシステムにインストールされると、永続登録は、スプレッドシートオブジェクトのクラスの利用性を反映するように更新される。スプレッドシート開発者が、インタフェースによって定義された各関数メンバを実現しそして永続登録が維持される限り、ワードプロセッシングプログラムは、開発者のスプレッドシートオブジェクトのインスタンスをワードプロセッシング文書に埋め込むことができる。ワードプロセッシングプログラムは、その埋め込まれたスプレッドシートオブジェクトの関数メンバを、誰がそれを実現したか又はそれらがどのように実現されたかに係わりなく、アクセスする。
【００２２】
しかし、種々のスプレッドシート開発者は、ある関数メンバのみを実現したいであろう。例えば、あるスプレッドシート開発者は、データベース支援は実現したくないが、他の全ての関数メンバは支援したいであろう。オブジェクトを埋め込むことができる上に、スプレッドシートの開発者が関数メンバの一部のみを支援できるようにするため、スプレッドシートオブジェクトに対して多数のインタフェースが定義される。例えば、インタフェースIDatabase 及びIBasicは、下記のようにスプレッドシートに対して定義できる。
0004322967.tif 000006
各スプレッドシート開発者は、IBasicインタフェースを実現し、IDatabase インターフェイスを任意に実行する。
【００２３】
実行時に、ワードプロセッシングプログラムは、埋め込まれるべきスプレッドシートオブジェクトがIDatabase インタフェースを支援するかどうかを決定しなければならない。この決定をするために、どのインタフェースがオブジェクトに対して実現されるかを指示する関数メンバと共に別のインタフェース（各スプレッドシートオブジェクトが実現する）が定義される。このインタフェースは、IUnknownという名称であり（そして未知のインタフェース又はオブジェクト管理インタフェースと称され）、下記のように定義される。
0004322967.tif 000007
このIUnknownインタフェースは、関数メンバ（メソッド）QueryInterfaceを定義する。メソッドQueryInterfaceには、（タイプREFIIDの）パラメータiid においてインタフェース識別子（例えば、IDatabase ）が通され、そしてこのメソッドがパラメータppv において呼び出されるオブジェクトに対し識別されたインタフェースの実現を指すポインタを返送する。このオブジェクトがインタフェースを支援しなければ、このメソッドは偽を返送する。タイプHRESULT は、予め定義された状態を指示し、タイプREFIIDは、インターフェイス識別子に対する参照を指示し、そしてタイプULONG は、非サインの長い整数を指示する。
0004322967.tif 000008
【００２４】
コード表１は、クラスＸＸに対するメソッドQueryInterfaceを一般的に実現するＣ＋＋擬似コードを含み、これは、クラスIUnknownを継承する。スプレッドシートオブジェクトがIDatabase インタフェースを支援する場合、メソッドQueryInterfaceはswitchステートメント内に適切なcaseラベルを含む。変数pIBasic とpIDatabaseは、各々、IBasicインタフェースとIDatabase インタフェースの仮想関数表に対するポインタを指す。メソッドQueryInterfaceは、インタフェースのポインタが返送されるときにクラスＸＸのオブジェクトに対する参照カウント値をインクリメントするためにメソッドAddRef（以下に述べる) を呼び出す。
0004322967.tif 000009
【００２５】
インタフェースIUnknownは、メソッドAddRef及びRelease も定義し、これらは参照カウントの実行に使用される。インタフェースに対する新たな参照が形成されるときに、メソッドAddRefを呼び出し、オブジェクトの参照カウントをインクリメントする。参照がもはや必要なくなると、メソッドRelease を呼び出し、オブジェクトの参照カウントをディクリメントし、参照カウントが０になったときに、オブジェクトの割当てを解除する。コード表２は、クラスＸＸに対するメソッドAddRef及びRelease を一般的に実現するＣ＋＋擬似コードを含み、これは、クラスIUnknownを継承する。
【００２６】
IDatabase インタフェースとIBasicインタフェースはIUnknownインタフェースを継承する。下記の定義は、IUnknownインタフェースの使用法を示す。
0004322967.tif 000010
【００２７】
図２は、ネスト状クラスを用いたスプレッドオブジェクトのデータ構造例を示すブロック図である。このスプレッドオブジェクトは、オブジェクトデータ構造２０１と、IBasicインタフェイスデータ構造２０３と、IDatabase インターフェイスデータ構造２０４と、仮想関数表２０２、２０５及び２０６と、メソッド２０７ないし２２１とを含む。オブジェクトデータ構造２０１は、仮想関数表２０２に対するポインタと、IBasic及びIDatabase インタフェイスに対するポインタとを含む。仮想関数表２０２の各エントリは、IUnknownインタフェイスのメソッドに対するポインタを含む。IBasicインタフェイスデータ構造２０３は、仮想関数表２０５に対するポインタを含む。仮想関数表２０５の各エントリは、IBasicインタフェイスのメソッドに対するポインタを含む。IDatabase インタフェース構造２０４は、仮想関数表２０６に対するポインタを含む。仮想関数表２０７の各エントリは、IDatabase インタフェースのメソッドのポインタを含む。IBasic及びIDatabase インタフェースは、IUnknownインタフェースを継承するので、仮想関数表２０５及び２０６は、メソッドQueryInterface、AddRef及びRelease に対するポインタを各々含む。以下、オブジェクトデータ構造は、オブジェクトをアクセスすることのできるインタフェースでラベル付けした形式２２２により表わされる。
【００２８】
下記の擬似コードは、スプレッドシートオブジェクトがIDatabase インタフェースを支援するかどうかをワードプロセッシングプログラムがいかに決定するかを示す。
if(pSpreadsheet->QueryInterface(“IDatabse",& pIDatabase))
// IDatabase Supported
else
// IDatabase not Supported
ポインタ pSpreadsheet は、図２に示すスプレッドシートクラスのインスタンスに対するポインタである。（pSpreadsheetは、データ構造２１０を指す。）このオブジェクトがIDatabase インタフェースを支援する場合は、メソッド２０７により定義されたメソッドQueryInterfaceは、IDatabase データ構造２０４を指すようにポインタpIDatabaseをセットし、その値として真を返送する。
【００２９】
通常、オブジェクトは、変数「宜言」又は「新たな」演算子によって具体化することができる（メモリ内に作成したオブジェクトのインスタンス）。しかし、どちらの具体化技術も、コンパイル時にクラス定義を必要とする。ワードプロセッシングプログラムが実行時にスプレッドシートオブジェクトを具体化できるためには別の技術が必要とされる。その１つの技術は、グローバルな関数CreateInstanceXXを与え、これは、次のように定義される。
static void CreateInstanceXX(REFIID iid, void**ppv) = 0 ;
メソッドCreateInstanceXXは、クラスＸＸのオブジェクトを実現化し、ポインタppv をパラメータiid により定義されたオブジェクトのインタフェースへ戻す。
【００３０】
【発明が解決しようとする課題】
本発明の目的は、オブジェクトを集合する方法及びシステムを提供することである。
【００３１】
本発明の別の目的は、オブジェクトの動作を動的に変更する方法及びシステムを提供することである。
【００３２】
本発明の更に別の目的は、オブジェクトを動的に集合する方法及びシステムを提供することである。
【００３３】
本発明の更に別の目的は、オブジェクトを静的に集合する方法及びシステムを提供することである。
【００３４】
本発明の更に別の目的は、オブジェクトを別のオブジェクト内に囲う一方、その囲まれたオブジェクトのインターフェイスをその囲んでいるオブジェクトのクライエントへ提示する方法及びシステムを提供することである。
【００３５】
本発明の更に別の目的は、囲んでいるオブジェクトが具体化された後にオブジェクトを別のオブジェクト内に囲む方法及びシステムを提供することである。
【００３６】
本発明の更に別の目的は、異なるタイプのオブジェクトを単一のオブジェクトへと動的に組み合わせる方法及びシステムを提供することである。
【００３７】
本発明の更に別の目的は、オブジェクトの実現を変更せずに別のオブジェクト内に囲むことができるか又は別のオブジェクト内に囲まれないようなオブジェクトを実現する方法及びシステムを提供することである。
【００３８】
本発明の更に別の目的は、オブジェクトが集合であることをクライエントが分からないような集合オブジェクトを実現する方法及びシステムを提供することである。
【００３９】
本発明の更に別の目的は、囲まれたオブジェクトそれ自体が任意の囲い込みレベルに対して囲んでいるオブジェクトとなり得るようなオブジェクトを囲い込む方法及びシステムを提供することである。
【００４０】
本発明の更に別の目的は、新たなインターフェイスを追加することによりベースオブジェクトの動作を増強する方法及びシステムを提供することである。
【００４１】
本発明の更に別の目的は、ベースオブジェクトの標準的な動作をオーバーライドするインターフェイスを追加することによりベースオブジェクトの見掛け上の動作を増強する方法及びシステムを提供することである。
【００４２】
本発明の更に別の目的は、囲まれた又は囲んでいるオブジェクトがデフォールト機能を実現するように、囲んでいるオブジェクト内にオブジェクトを囲むことにより、オブジェクトにデフォールト機能を与える方法及びシステムを提供することである。
【００４３】
本発明の更に別の目的は、囲まれたオブジェクト内に存在する共通の機能に対して制御動作を実現する方法及びシステムを提供することである。そして本発明の更に別の目的は、２つ以上の囲まれたオブジェクトによって実施されるインターフェイスをクライエントが要求するときにクライエントにどのインターフェイスを与えるかを決定する方法及びシステムを提供することである。
【００４４】
【課題を解決するための手段】
上記の目的、及び本発明の以下の説明において明らかとなる他の目的は、コンピュータシステム内にオブジェクトを集合させる方法及びシステムによって達成される。好ましい実施例では、本発明の方法は、囲まれたオブジェクトを、囲んでいるオブジェクト内に集合させる。この囲まれたオブジェクトは、オブジェクト管理インタフェース及び１つ以上の外部インタフェースを有し、一方、囲んでいるオブジェクトは、制御オブジェクト管理インタフェースを有する。集合オブジェクトによってクライアントに提示される各インタフェースは、インターフェイスの識別子を受け取ってその識別されたインターフェイスに対する参照を返送する問合せ関数メンバを有する。囲んでいるオブジェクトの制御オブジェクト管理インタフェースの問合せ関数メンバは、囲んでいるオブジェクトによって提示されたインタフェースの識別子を受取り、その提示されたインタフェースに対する参照を返送する。本発明の好ましい方法では、囲まれたオブジェクトのインスタンスを作成する。囲まれたオブジェクトの提示されたインタフェースの問合せ関数メンバは、インタフェースの識別子を受け取ると、その受け取った識別子を通すように上記囲んでいるオブジェクトの制御オブジェクト管理インタフェースの問合せ関数メンバを呼び出し、そして上記囲んでいるオブジェクトの制御オブジェクト管理インタフェースの呼び出された問合せ関数メンバによって戻される参照を、識別されたインタフェースの参照として返送する。
【００４５】
静的な集合の好ましい実施例では、囲まれたオブジェクトの問合せ関数メンバは、囲まれたオブジェクトの外部インターフェイスの知識で実現され、囲んでいるオブジェクト又は他の囲まれたオブジェクトのインターフェイス（制御オブジェクト管理インターフェイス以外の）の知識をもたない。囲んでいるオブジェクトの制御オブジェクト管理インターフェイスの問合せ関数メンバは、囲まれたオブジェクトの提示されたインターフェイスの知識で実現される。
【００４６】
動的な集合の好ましい実施例では、オブジェクトによって実現されるインターフェイスインターフェイスをクライエントプログラムの実行中に集合できるようにすることによりオブジェクトを動的に変更することができる。インターフェイスは、それらを実現するオブジェクトをマルチタイプオブジェクトへと動的に囲い込むことにより集合される。追加されるべき各インターフェイスは、集合される能力をもつオブジェクトによって実現される。マルチタイプオブジェクトは、囲んでいるオブジェクトとして働くように形成される。マルチタイプオブジェクトは、追加インターフェイス関数メンバを有し、これは、囲んでいるマルチタイプオブジェクトにインターフェイスを追加することによりインターフェイスを集合するように使用できる。又、マルチタイプオブジェクトは、オブジェクトの全てのインターフェイスを集合するための追加オブジェクト関数も有する。又、マルチタイプオブジェクトは、クライエントから要求があった際にその追加されたインターフェイスに対する参照を検索するための問合せ関数も有している。この問合せ関数メンバは、囲んでいるマルチタイプオブジェクトの制御オブジェクト管理インターフェイスの一部分である。又、集合されるべきインターフェイスを実現するオブジェクトのインスタンスも形成される。その形成中に、囲んでいるマルチタイプオブジェクトに対するポインタが、囲まれるべきオブジェクトに通され、囲まれたオブジェクトが囲んでいるマルチタイプオブジェクトと通信できるようにする。集合されるべきインターフェイスを実現する形成されたオブジェクトは、集合されるべきインターフェイスに対する参照の検索をサポートする問合せ関数メンバを有する。好ましい方法は、囲んでいるマルチタイプオブジェクトの追加インターフェイス関数メンバ又は追加オブジェクト関数メンバを呼び出し、これに、集合されるべきインターフェイス実現する形成されたオブジェクトに対する参照を通す。その後に、囲んでいるマルチタイプオブジェクトの問合せ関数メンバが呼び出され、集合されたインターフェイスに対する参照が検索される。
【００４７】
【実施例】
本発明は、オブジェクトを集合するためのコンピュータシステムにおける方法を提供する。オブジェクトは、静的又は動的に集合することができる。静的な集合を用いると、囲んでいるオブジェクトは、典型的に、囲まれたオブジェクトの提示されたインターフェイスについてのコンパイル時知識を有する。それ故、囲んでいるオブジェクトのオブジェクト管理インターフェイスは、この知識を用いて、囲まれたオブジェクトの提示されたインターフェイスへインターフェイスポインタを返送するようにカスタマイズされる。これらの静的に集合されたオブジェクトのインスタンスは、動的に（実行時に）形成される。
【００４８】
動的な集合を用いると、囲んでいるオブジェクトが具体化され、これを用いてオブジェクト又はインターフェイスを実行時に集合することができる。囲んでいるオブジェクトは、囲まれたオブジェクト又はインターフェイスについての前もった知識をもたず、従って、囲んでいるオブジェクトによりコンパイル時知識が使用されない。同様に、囲まれたオブジェクト及びインターフェイスは、オブジェクト及びインターフェイスを集合するのに使用される制御オブジェクト管理インターフェイス除いて、囲んでいるオブジェクトのインターフェイスの実現又は存在についての知識をもたない。又、集合されたオブジェクト及びインターフェイスへのアクセスを制御するためのルールメカニズムも設けられる。
【００４９】
これらタイプの集合の各々は、以下で詳細に説明する。好ましい実施例では、本発明の方法及びシステムは、中央処理ユニット、メモリ及び入力／出力装置を含むコンピュータシステムにおいて実現される。
【００５０】
静的な集合
静的な集合の好ましい実施例において、集合オブジェクトはそのクライアントに複数のインタフェースを与える。オブジェクトを具体化するコンピュータプログラムをクライアントと呼ぶ。集合オブジェクトは、１つ以上の囲まれたオブジェクトと、IUnknownインタフェースの実現部とからなり、この実現部を集合オブジェクトの制御IUnknownインタフェースと呼ぶ。集合オブジェクトは、そのクライアントにそれ自体のインタフェースと囲まれたオブジェクトからのインタフェースを提示する。制御IUnknownインタフェースのメソッドQueryInterfaceはポインタを集合オブジェクトによって提示された各インタフェースに戻す。集合オブジェクトは各囲まれたオブジェクトを具体化する。この具体化は、集合オブジェクトの構成中に実行できるし、囲まれたオブジェクトのインタフェースが必要になるまで延期することもできる。各囲まれたオブジェクトは、制御IUnknownインタフェースに対するポインタを含む。囲まれたオブジェクトの提示されたインタフェースのメソッドQueryInterfaceは、IUnknownインタフェースのメソッドQueryInterfaceを呼び出すように実現されるのが好ましい。囲まれたオブジェクトが実現される場合に、一般に開発者は、囲んでいるオブジェクトがどんなインタフェースを提示するかについての知識はない。その結果、囲まれたオブジェクトのメソッドQueryInterfaceが制御IUnknownインタフェースを呼び出して、要求したインタフェースのポインタを検索する。制御IUnknownインタフェースのメソッドQueryInterfaceは、一般に、提示された全てのインタフェースの知識をもって実現される。オブジェクトが囲まれない場合は、制御IUnknownインタフェースは、そのオブジェクトのIUnknownインタフェースである。逆に、オブジェクトが囲まれる場合は、制御IUnknownインタフェースは囲んでいるオブジェクトのIUnknownインタフェースである。
【００５１】
好ましい実施例では、集合オブジェクトが参照カウントを維持する。集合オブジェクトが具体化される場合に、その参照カウントは、１にセットされる。制御IUnknownのメソッドQueryInterfaceは、参照がクライアントに戻されるときに、参照カウントをインクリメントする。囲まれたオブジェクトの提示されたインタフェースのメソッドAddRefは、制御IUnknownインタフェースのメソッドAddRefを呼び出し、集合オブジェクトの参照カウントをインクリメントする。同様に、囲まれたオブジェクトの提示されたインタフェースのメソッドRelease は、制御IUnknownインタフェースのRelease を呼び出し、集合オブジェクトの参照カウントをディクリメントすると共に、参照カウントが０のときに集合オブジェクトを削除する。囲まれたオブジェクトが具体化される場合には、囲まれたオブジェクトの参照カウントは、１にセットされる。集合オブジェクトが削除された場合は、各囲まれたオブジェクトのIUnknownインタフェースのメソッドRelease が呼び出され、囲まれたオブジェクトを消去する。
【００５２】
図３は、集合オブジェクトを示すブロック図である。集合オブジェクトＳ３はインタフェイスＡ、Ｂ、Ｃ、Ｆ及び制御IUnknownを提示する。集合（囲んでいる）オブジェクトＳ３は、囲まれたオブジェクトＳ１  ３０３、囲まれたオブジェクトＳ２  ３０２、及び実現部Ｉ３  ３０４を含む。囲まれたオブジェクトＳ１は、外部インタフェイスＣ及びＤを実現し、囲まれたオブジェクトＳ２は、外部インタフェイスＥ及びＦを実現する。（外部インタフェイスとは、囲んでいるオブジェクトによって提示できるオブジェクトのインタフェイスである。内部インタフェイスとは、囲んでいるオブジェクトによっては提示できないオブジェクトのインタフェイスである。）実現部Ｉ３は、外部インタフェースＡ及びＢと制御IUnknownを実現する。集合オブジェクトＳ３のクライアントは、オブジェクトが集合体であることが分かる必要はない。集合オブジェクトＳ３は、オブジェクトＳ１及びＳ２を集合オブジェクトＳ３の構成中又はそれより遅い時間に具体化する。実現部Ｓ３は、オブジェクトＳ１及びＳ２のIUnknownインタフェイスに対するポインタを含む。オブジェクトＳ１及びＳ２は、制御IUnknownインタフェイスに対するポインタを含むように初期化される。
【００５３】
提示されたインタフェイスのメソッドQueryInterfaceは、提示された各インタフェイスに対するポインタを返送し、そしてポインタが返送されたときに集合オブジェクトの参照カウントをインクリメントすることができる。制御IUnknownのメソッドQueryInterfaceは、実現部Ｉ３が実現するインターフェイスＡ、Ｂ及び制御IUnknownのポインタに直接アクセスし、そして囲まれたオブジェクトのIUnknownインタフェースのメソッドQueryInterfaceを呼び出して、囲まれたオブジェクトＳ１及びＳ２の提示されたインタフェイスＣ及びＦに対するポインタを検索する。囲まれたインタフェイスに対するポインタを返送するときには、制御IUnknownインタフェースのメソッドQueryInterfaceは、制御IUnknownインタフェイスのメソッドAddRefを呼び出すことにより、集合オブジェクトＳ３の参照カウントをインクリメントする。（制御IUnknownインタフェース以外の）各提示されたインタフェースのメソッドQueryInterfaceは、制御IUnknownインタフェースのメソッドQueryInterfaceを呼び出すのが好ましい。
0004322967.tif 000011
0004322967.tif 000012
0004322967.tif 000013
【００５４】
コード表３は、オブジェクトＳ１の好ましいクラス定義に対してＣ＋＋擬似コードを含み、これは、オブジェクトのインスタンスを作成するグローバル関数と共に集合体（集合可能なオブジェクト）内に囲い込むことができる。クラスIUnknown、IC及びIDは、各インタフェイスのメソッドを定義するインタフェイスである。クラスＳ１は、IUnknownインタフェイス、ICインタフェイス及びIDインタフェイスを実現する。クラスＳ１は、IC及びIDインタフェイスを外部インタフェイスとして実現する。図４は、クラスＳ１のオブジェクトのインスタンスのデータ構造レイアウトのブロック図である。インスタンス構造４０１は、クラスＳ１のデータメンバ（ m C 、 m D 、 m punkOuter 、 m refcount）と、仮想関数表ポインタ（S1::vfptr)に対するポインタを含む。データメンバ m C 及び m D は、各々クラスＣ及びＤのオブジェクトのインスタンスである。クラスＣ及びクラスＤは、クラスＳ１のフレンドであり、オブジェクトＣ及びＤがクラスＳ１のプライベートメンバをアクセスできるようにする。仮想関数表ポインタS1::vfptr は、仮想関数表４０２を指し、データメンバ内の仮想関数表ポインタ m C S1::C::vfptrは、仮想関数表４０３を指し、更に、データメンバ内の仮想関数表ポインタ m D S1::D::vfptrは、仮想関数表４０３Ａを指す。仮想関数表４０２は、IUnknownインタフェイス用に定義した仮想関数に対するポインタを含み、仮想関数表４０３は、Ｃインタフェイス用に定義した仮想関数に対するポインタを含み、仮想関数表４０３Ａは、インタフェイスＤ用に定義した仮想関数に対するポインタを含む。仮想関数表４０３及び４０３Ａ内の省略部分は、クラスＣ及びＤの付加的な関数メンバに対するポインタを各々示している。関数４０４ないし４０８は、クラスＳ１の関数メンバである。関数４０７は、クラスＳ１の構成子である。関数４０８は、クラスＳ１の関数CreateInstanceである。関数４０９ないし４１２は、クラスＣの関数メンバである。関数４１２は、クラスＣの構成子である。関数４１３ないし４１６は、クラスＤの関数メンバである。関数４１６は、クラスＤの構成子である。
【００５５】
コード表３に示したように、メソッドS1::QueryInterfaceは、インタフェイスＣ、インタフェイスＤ、又はインタフェイスIUnknownに対するポインタを返送する。インターフェイスＣ又はインターフェイスＤに対するポインタが返送されるときには、メソッドS1::QueryInterfaceは、メソッドS1::AddRefを呼び出し、オブジェクトＳ１の参照カウントをインクリメントする。メソッドS1::AddRefは、参照カウントをインクリメントし、そしてメソッドS1::Release は、参照カウントをディクリメントすると共に、参照カウントが０になったときにオブジェクトＳ１を削除する。
【００５６】
グローバル関数CreateInstanceS1は、クラスＳ１のオブジェクトのインスタンスを作成する。クライアントがこの関数を呼び出し、クラスＳ１のオブジェクトを具体化する。従って、クライアントは、コンパイル時間又は実行時にクラスＳ１の定義にアクセスせずに、クラスＳ１のオブジェクトを具体化できる。具体化されたオブジェクトＳ１が、集合オブジェクト及び返送すべきインタフェースの識別子iid 内に囲まれるときに、関数CreateInstanceS1に、制御IUnknown（punkOuter)に対するポインタが通される。関数CreateInstanceS1は、識別されたインタフェースに対するポインタ（ppv)を返送する。関数CreateInstanceS1は、パラメータpunkOuter を通すようにメソッドS1::CreateInstanceを呼び出す。メソッドS1::CreateInstanceは、オブジェクトＳ１を具体化し、そしてオブジェクトＳ１のIUnknownインタフェースに対するポインタ（punk) を返送する。関数CreateInstanceS1は、オブジェクトＳ１のメソッドQueryInterfaceを呼び出し、識別されたインタフェースに対するポインタを検索する。関数CreateInstanceS1は、次いで、オブジェクトＳ１のメソッドRelease を呼び出すが、これは、一時ポインタpunkがもはや必要ないからである。
【００５７】
メソッドS1::CreateInstanceは、オブジェクトＳ１を具体化し、オブジェクトＳ１のIUnknownインタフェースに対するポインタ（ppunk)を返送する。メソッドS1::CreateInstanceには、制御IUnknownに対するポインタ（punkOuter)が通される。メソッドS1::CreateInstanceは新たな演算子を使用して、オブジェクトＳ１を具体化する。具体化の間に、構成子S1::S1を呼び出し、パラメータpunkOuter の値を通す。オブジェクトＳ１が構成された後に、メソッドS1::CreateInstanceは、メソッドS1::QueryInterfaceを呼び出し、オブジェクトＳ１のIUnknownインタフェイスに対するポインタを検索する。
【００５８】
構成子S1::S1は、データメンバ m C 、 m D 、 m punkOuter 及び m refcountを初期化する。構成子S1::S1にはパラメータpunkOuter が通される。データメンバ m C 及び m D の具体化中、構成子C::C及びD::Dを呼び出し、オブジェクトＳ１に対するポインタthisを通す。パラメータpunkOuter の値がNULLであれば、構成子S1::S1はデータメンバ m punkOuter をポインタthisの値にセットする（このポインタは、新たに具体化したオブジェクトＳ１を指す）。パラメータpunkOuter の値がNULLでなければ、構成子S1::S1は、データメンバ m punkOuter をパラメータpunkOuter の値にセットする。データメンバ m punkOuter は、オブジェクトＳ１が囲まれている場合には、集合体の制御IUnknownの値を指し、そしてオブジェクトＳ１が囲まれていない場合には、オブジェクトＳ１の制御IUnknownを指す。構成子S1::S1は、データメンバ m fercountをゼロに初期化もする。
【００５９】
構成子C::CにはオブジェクトＳ１に対するポインタが通される。構成子C1::C1は、通されたポインタをデータメンバC::m pS1 内に格納する。このデータメンバC::m pS1 は、クラスＣのメソッドによって使用され、データメンバS1:: m punkOuter にアクセスする。
【００６０】
メソッドC::QueryInterface 、C::AddRef 及びC::Releaseは、データメンバS1:: m punkOuter により指されたIUnknownインタフェースの対応メソッドを呼び出し、これは、オブジェクトＳ１が囲まれるときに集合体の制御IUnknownInterface を指す。
【００６１】
クラスＤの構成子及びその他のメソッドは、クラスＣの構成子及びその他のメソッドに類似している。
【００６２】
図４は、集合体の部分でないオブジェクトＳ１のインスタンスを示す。データメンバS1::C::m pS1 、S1::D::m pS1 及び S1::m punkOuter は、オブジェクトＳ１自体に対するポインタに初期化される。データメンバ m C 及びm  D のメソッドQueryInterface、AddRef及びRelease は、オブジェクトＳ１のインタフェースのIUnknownメソッドを呼び出す。
【００６３】
インタフェイスＥ及びＦを実現するオブジェクトＳ２は、上述のオブジェクトＳ２と類似している。
0004322967.tif 000014
0004322967.tif 000015
0004322967.tif 000016
0004322967.tif 000017
【００６４】
コード表４は、集合オブジェクトの好ましいクラス定義に対するＣ＋＋擬似コードを含む。クラスＳ３は、インタフェイスIUnknownＡ、Ｂ、Ｃ及びＦを提示する。インタフェイスＣを与えるために、クラスＳ３はオブジェクトＳ１を囲み、インタフェイスＣを提示する。インタフェイスＦを与えるために、クラスＳ３はオブジェクトＳ２を囲み、インタフェイスＦを提示する。オブジェクトＳ３は、インタフェイスＣ及びＦに対するポインタを制御IUnknownインタフェイスのメソッドQueryInterfaceを介して戻すことによってインタフェイスＣ及びＦを提示する。オブジェクトＳ１のインタフェイスＤ及びオブジェクトＳ２のインタフェイスＥは、外部インタフェイスであるが、オブジェクトＳ３はこれらのインタフェイスを提示しない。
【００６５】
メソッドS3::QueryInterface、S3::AddRef及びS3::Release は、集合体の制御IUnknownインタフェイスを構成する。メソッドS3::QueryInterfaceは、制御IUnknownインタフェイスＡ、Ｂ、Ｃ及びＦに対するポインタを返送する。制御IUnknownインタフェイスのポインタが返送されるときは、メソッドS3::QueryInterfaceは、メソッドS3::AddRefを呼び出して、オブジェクトＳ３に対する参照カウントをインクリメントする。メソッドS3::AddRefは、参照カウントをインクリメントし、メソッドS3::Release は参照カウントをディクリメントし、参照カウントが０になるとオブジェクトＳ３を削除する。インタフェイスＡ、Ｂ、Ｃ又はＦに対するポインタが返送されるときは、メソッドS3::QueryInterfaceは、制御IUnknownインタフェイスのメソッドS3::AddRefを呼び出し、これは、Ｓ３オブジェクトが集合されないときは、メソッドS3::AddRefである。
【００６６】
グローバル関数CreateInstanceS3は、クラスＳ３のオブジェクトのインスタンスを作成する。クライアントは、この関数を呼び出して、クラス３のオブジェクトを具体化する。このため、クライアントは、コンパイル時及び実行時にクラスＳ３の定義にアクセスせずにクラスＳ３のオブジェクトを具体化できる。具体化されたオブジェクトＳ３が、集合オブジェクト、及びクラスＳ３により提示されたインタフェイスの識別子（iid)に囲まれて戻される場合に、関数CreateInstanceS3には、制御IUnknownインタフェイス（punkOuter)に対するポインタが通される。関数CreateInstanceS3は識別されたインタフェイスに対するポインタ(ppv) を戻す。関数CreateInstanceS3は、パラメータpunkOuter を通すようにメソッドS3::CreateInstanceを呼び出す。メソッドS3::CreateInstanceは、オブジェクトＳ３を具体化し、オブジェクトＳ３のIUnknownインタフェイスに対するポインタ（punk）を戻す。関数CreateInstanceS3は、メソッドS3::QueryInterfaceを呼び出し、識別されたインタフェイスに対するポインタを検索する。一時的ポインタpunkは不要になるので、関数CreateInstanceS3は、メソッドS3::Release を呼び出す。
【００６７】
メソッドS3::CreateInstanceは、オブジェクトＳ３を具体化し、オブジェクトＳ３のIUnknownに対するポインタ（ppunk)を戻す。メソッドS3::CreateInstanceには、制御IUnknownに対するポインタ（punkOuter)が通される。メソッドS3::CreateInstanceは、新たな演算子を使用してオブジェクトＳ３を具体化する。具体化の間に、構成子S3::S3を呼び出し、パラメータpunkOuter を通す。オブジェクトＳ３が構成された後、メソッドS3::CreateInstanceは関数CreateInstanceS1を呼び出し、囲まれたオブジェクトＳ１を作成する。メソッドS3::S3CreateInstanceはパラメータpS3->m punkOuter 及びびIUnknownインタフェイスのインタフェイス識別子を通し、オブジェクトＳ１のIUnknownインタフェースに対するポインタが返送される。メソッドS3::CreateInstanceは、データメンバS3:: m punkS1内にその返送されたポインタを格納する。メソッドS3::CreateInstanceは、関数CreateInstanceS2を呼び出し、オブジェクトＳ１の作成と同様の方法でオブジェクトＳ２を作成する。メソッドS3::CreateInstanceは、メソッドS3::QueryInterfaceを呼び出し、IUnknownインターフェイスに対するポインタを検索する。
【００６８】
メソッドS3::AddRefは、オブジェクトＳ３の参照カウントをインクリメントする。メソッドS3::Release は、参照カウントをディクリメントする。参照カウントが０になると、メソッドS3::Release は、オブジェクトＳ３を削除する。
【００６９】
構成子S3::S3は、データメンバ m A 、 m B 、 m punkouter 及び m refcountを初期化する。構成子S3::S3にはパラメータpunkOuter が通される。データメンバ m A 及び m B の具体化の間に、構成子 A::A 及び B::B が呼び出されそしてオブジェクトＳ３対応のポインタthisが通される。パラメータpunkOuter の値がNULLであれば、構成子S3::S3は、（新たに具体化したオブジェクトＳ３を指す）ポインタthisの値にデータメンバ m punkOuter をセットする。パラメータpunkOuter の値がNULLでない場合には、構成子S3::S3はデータメンバ m punkOuter をパラメータpunkOuter の値にセットする。データメンバ m punkOuter は、オブジェクトＳ３が囲まれている場合には、集合体の制御IUnknownインタフェイスの値を指し、オブジェクトＳ３が囲まれていない場合には、オブジェクトＳ３のIUnknownインタフェイスを指す。構成子S3::S3は、データメンバ m refcountを０に初期化する。
【００７０】
消去関数S3::-S3 は、メソッドS1::Release を呼び出して、囲まれたオブジェクトＳ１の参照カウントをディクリメントする。オブジェクトＳ１の具体化の間に参照カウントは１にセットされているので、メソッドS1::Release はオブジェクトＳ１を削除する。消去関数S3::-S3 は、同様の方法でオブジェクトＳ２の参照カウントをディクリメントする。
【００７１】
インタフェイスＡ及びＢは、インタフェイスＣのメソッドと同様の動作を有する。従って、インタフェースＡ及びＢは、オブジェクトＳ３が囲まれた場合に提示できる。
【００７２】
図５は、オブジェクトＳ３のデータ構造レイアウトを示すブロック図である。このデータ構造レイアウトは、インスタンスデータ５０１、仮想関数表５０２、５０３及び５０４、メソッド５０５ないし５１７、オブジェクトＳ１  ４０１ないし４１３、及びオブジェクトＳ２  ５１９を含む。インスタンスデータ５０１は、制御IUnknownインタフェイスの仮想関数表に対するポインタと、クラスＡ及びＢのインスタンスであるデータメンバ m A 及び m B と、オブジェクトＳ３のIUnknownインタフェースを指すデータメンバ m punkOuter と、オブジェクトＳ３対応の参照カウントを含むデータメンバ m refcountと、囲まれたオブジェクトＳ１のIUnknownインターフェイスを指すデータメンバ m punkS1と、囲まれたオブジェクトＳ２  ５１９のIUnknownインタフェイスを指すデータメンバ m punkS2とを含む。囲まれたオブジェクトＳ１が具体化されると、そのデータメンバ S1::m punkOuter は初期化され、オブジェクトＳ３のIUnknownインタフェースを指す。同様に、囲まれたオブジェクトＳ２が具体化されると、そのデータメンバ S2::m punkOuter は初期化され、オブジェクトＳ３のIUnknownインタフェースを指す。
【００７３】
図６及び図７は、囲んでいるオブジェクトと囲まれたオブジェクトとの共同動作を示すブロック図である。図６は、別のオブジェクトに囲まれていないクラスＳ１のオブジェクトを示すブロック図である。クラスＳ１のオブジェクト６０１はデータメンバ m punkOuter を含み、これはIUnknownインタフェースと、メソッド６０３、６０４、６０５及び６０６を指す。メソッドIUnknown::QueryInterface６０３は、要求されたインタフェイスに対するポインタを戻し、参照カウントをインクリメントする。メソッド C::QueryInterface６０５及び C::AddRef６０６は、IUnknownインタフェースの対応するメソッドを呼び出す。クラスＤのメソッドの実現部（図示せず）は、クラスＣと同様である。図７は、クラスＳ１及びＳ２のオブジェクトを囲むクラスＳ３のオブジェクトを示す図である。オブジェクトＳ２は、オブジェクトＳ１と同様であり、図示していない。クラスＳ１のオブジェクト６０１のデータメンバ m punkOuter ６０２は、クラスＳ３のオブジェクト６１０のIUnknownインタフェイスを指す。メソッドIUnknown::QueryInterface６１３は、提示された各オブジェクトに対するポインタを返送し、データメンバ m punkS1  ６１９で指示されたメソッドIUnknown::QueryInterface６０３を呼び出し、インタフェースＣに対するポインタを検索する。データメンバ m punkOuter ６１２は、クラスＳ３オブジェクト６１０のIUnknownインターフェイスを指す。クラスＡ及びＢオブジェクトのメソッドQueryInterface６１５及び６１７は、データメンバ m punkOuter ６１２によって示されるメソッドを呼び出す。
【００７４】
上述の本発明の実施例において、集合体の制御IUnknownインタフェイスのメソッドQueryInterfaceは、囲まれたオブジェクトのIUnknownインタフェイスのメソッドQueryInterfaceを呼び出し、提示されたインタフェイスに対するポインタを検索する。本発明の別の実施例においては、囲んでいるオブジェクトが提示する囲まれたオブジェクトのインタフェイスに対するポインタを、囲んでいるオブジェクトがキャッシュ処理できる。従って、制御IUnknownのメソッドQueryInterfaceが呼び出されると、このメソッドは、囲まれたオブジェクトのIUnknownインタフェイスのメソッドQueryInterfaceを呼び出すのではなく、制御IUnknownインタフェイスのメソッドAddRefを呼び出した後に、そのキャッシュ処理されたポインタを検索して戻すことができる。この別の実施例を実現するためは、囲んでいるオブジェクトが、各キャッシュ処理されたポインタのデータメンバを定義する。囲まれたオブジェクトが具体化されるときは（一般に囲んでいるオブジェクトの構成中に）、囲まれたオブジェクトのIUnknownインタフェースのメソッドQueryInterfaceを呼び出して、提示されたインタフェイスのポインタを検索する。検索されたポインタは参照カウントされず、囲んでいるオブジェクトが囲まれたオブジェクトに対して１つのポインタ（例えば、S3:: m punkS1）のみを効果的に維持するのが好ましい。囲まれたオブジェクトは、メソッドRelease に対する１回のコールで削除することができる。従って、ポインタがキャッシュ処理された後に、囲まれたオブジェクトのIUnknownインタフェイスのメソッドRelease が呼び出され、そのキャッシュ処理されたポインタに属する参照カウントを除去する。
【００７５】
上述の本発明の実施例において、制御IUnknownインタフェイスのメソッドQueryInterfaceの実現部は、どのインタフェイスが提示されるかを指定するswitchステートメントを含む。例えば、メソッドS3::QueryInterfaceのswitchステートメントは、提示された各インタフェイスＡ、Ｂ、Ｃ及びＦと制御IUnknownに対するcaseラベルを含む。従って、提示されたインタフェイスは囲んでいるオブジェクトの実現中に静的に定義される。別の実施例においては、制御IUnknownインタフェイスメソッドQueryInterfaceは、囲まれたオブジェクトの外部インタフェイスに関する知識が特になくても実現できる。メソッドQueryInterfaceが、実現しないインタフェイスに対するポインタを返送するように要求されたときには、囲まれたオブジェクトのIUnknownインタフェイスのメソッドQueryInterfaceを呼び出し、囲まれたオブジェクトにより実現されれば、その識別されたインタフェイスに対するポインタを検索する。コード表５は、この別の実施例を実現するオブジェクトＳ３の制御IUnknownのメソッドQueryInterfaceの好ましい実現に対するＣ＋＋擬似コードである。囲まれたたオブジェクトの外部インタフェイスに対するポインタを戻すことに加えて、制御IUnknownのメソッドQueryInterfaceは、他の全ての外部インタフェイスを提示する一方、特定の外部インタフェースを提示しないように実現できる。
0004322967.tif 000018
【００７６】
上述の実施例において、エラーチェックについては述べなかった。種々の形式ののエラーチェックを実行して、集合体が適切に作成されるよう確保することが望ましい。例えば、囲んでいるオブジェクトが、集合できないオブジェクトを囲もうと試みた場合には、囲んでいるオブジェクトの具体化が失敗に終わる（例えば、関数CreateInstanceS1が欠陥を示すフラグを返送する）。
【００７７】
上述の実施例では、集合オブジェクトそれ自体は、囲んでいるオブジェクト内に囲まれたオブジェクトとなり得る。この囲い込み（ネスティング）は、いかなる深さでも起こり得る。或いは又、集合オブジェクトは、非集合可能に実施することもできる。クラスＸＸに対する関数CreateInstanceXXは、パラメータpunkOuter がナルでない場合、即ち、集合が所望される場合に欠陥を示すフラグを返送することができる。
【００７８】
上述の実施例では、集合可能なオブジェクトの各外部インタフェイスに対するオブジェクトは、集合可能なオブジェクトのデータメンバとして具体化される。別の実施例においては、外部インタフェイスは、集合可能なオブジェクトのデータメンバとして実現されるのではなく、集合可能なオブジェクトによって継承される。コード表６は、外部インタフェイスＣ及びＤを有する集合可能なクラスの好ましいクラス定義Ｓ１に対するＣ＋＋擬似コードを含む。クラスＳ１は、抽象クラスIC及びIDを継承する。インタフェースIC及びIDの実現部は、データメンバ m punkOuter にアクセスするために導出クラスＳ１に対するポインタを記憶する必要はないが、IUnknownインターフェイス(IUnknownS1)の特殊な非継承の実現部は必要とされる。これに対し、インタフェイスIC及びIDの実現部は、コード表３に示すように、導出クラスＳ１に対するポインタをデータメンバ m pS1 に記憶する。当業者であれば、インタフェイスの継承を用いた他の実現部も考えられるであろう。
0004322967.tif 000019
0004322967.tif 000020
【００７９】
動的な集合
動的集合の好ましい実施例においては、インターフェイスのインスタンスは、囲んでいるオブジェクトの形成後の任意の時間にその囲んでいるオブジェクトにこれらインスタンスを追加することによって組み合わされる。このようにして、新たな又は変更されたインターフェイスを既存の（ベース）オブジェクトと組み合わせて、そのベースオブジェクトのコードがコンパイル又はリンクされた後にベースオブジェクトの見掛け上の動作を変更することができる。即ち、ベースオブジェクトの動作（ベースオブジェクトのメソッドにより実行される）は外部には変更されたように見えるが、ベースオブジェクトの動作を実行するメソッドは、実際には変更されていない。ベースオブジェクトは、囲んでいるオブジェクト内に囲み込まれ、その後に、新たな又は変更されたインターフェイスが追加される。
【００８０】
外部の要求が特定のインターフェイスにアクセスされるときには、囲んでいるオブジェクトは、どのインターフェイスが返送するかそして一致するインターフェイスが２つ以上ある場合はその要求されたインターフェイスをいかに呼び出すかを決定する役目を果たす。例えば、集合オブジェクトに３つのIPrintインターフェイスが存在する場合には、囲んでいるオブジェクトは、どのIPrintインターフェイスが返送するか、或いはそれ自身のIPrintインターフェイスを返送するかどうかを決定し、これは、他のIPrintインターフェイスのメソッドの組み合わせをいかに呼び出すかを知る。囲んでいるオブジェクトは、固定の又は指定可能な１組の組み合わせルールからこの決定を行うことができる。
【００８１】
これらの組み合わせルールは、囲まれたベースオブジェクトの既に定義されたインターフェイスの新たな実現部にアクセスすることによりその囲まれたベースオブジェクトの標準的な動作をオーバーライドするのに使用できる。又、これらのルールは、囲まれたベースオブジェクトの一部分として最初に定義されない能力を追加することによりその囲まれたベースオブジェクトの動作を増強するのに使用することもできる。これらのオーバーライド及び増強能力の両方は、ベースオブジェクトに新たな又は変更されたインターフェイスを追加することによって与えられる。これらの能力に加えて、標準的な囲んでいるオブジェクトは、囲まれたオブジェクトに対するデフォールト動作を実行することができる（囲まれたオブジェクト又は追加されたインターフェイスによって与えられない場合に呼び出すための方法を実行するインターフェイス）。又は、標準的な囲んでいるオブジェクトは、全ての囲まれたオブジェクトに対して典型的に存在する方法（プリンティングのような）に対する制御（オーバーライド）動作を実行することができる。
【００８２】
好ましい実施例では、クライエントプログラムの実行中にインターフェイスのインスタンス（オブジェクトによって実行される）を一緒に集合できるようにすることによりオブジェクトを動的に変更することができる。オブジェクトを具体化するコンピュータプログラムは、クライエントプログラムである。集合は、それらの各々のインターフェイスを囲んでいるオブジェクト内に囲い込むことにより多数の異なるオブジェクトの能力を組み合わせるプロセスである。囲んでいるオブジェクトは、次いで、制御IUnknownインターフェイスの囲んでいるオブジェクトの実現部により提示しようとする全てのインターフェイスへのアクセスを支援するという役目を果たす。
【００８３】
静的な集合では、囲んでいるオブジェクトは、それが集合しようとするインターフェイス（オブジェクト）を前もって知る必要があった。静的な集合を用いると、プログラマは、囲んでいるオブジェクトが提示しなければならないのはその集合オブジェクトインターフェイスのどれかを前もって判断し、そしてその囲んでいるオブジェクトの制御IUnknownのQueryInterfaceメソッドを実施して、これらの提示されたインターフェイスに対するポインタを要求時に返送する。制御IUnknownのQueryInterfaceメソッドは、個々の囲まれたオブジェクトの対応するIUnknownインターフェイスに対する参照を維持することによりこのタスクを実行する。（これらの参照は、囲んでいるオブジェクトが、囲まれたオブジェクトを具体化するときに形成される。）１つの囲まれたオブジェクトの提示されたインターフェイスを参照するための要求が受け取られたときには、制御IUnknownのQueryInterfaceメソッドは、その要求に応答するために、囲まれたオブジェクトの対応するIUnknownインターフェイスを呼び出す。囲まれたオブジェクトは、囲んでいるオブジェクトがどのインターフェイスを提示するか知らないので、囲まれたオブジェクトによって受け取られる全ての外部要求は、囲んでいるオブジェクトへ通され、これにより、一緒に集合された他の囲まれたオブジェクトにおいて定義されたインターフェイスへアクセスできるようにする。
【００８４】
本発明は、インターフェイスの動的な集合も支援する。好ましい実施例では、囲んでいるオブジェクトは、具体化されたインターフェイスを登録しそしてそれらに対する参照を後で検索するメソッドを与える。更に、集合オブジェクトからインターフェイスが要求されたときには、本発明は、同じインターフェイスの２つ以上のインスタンスが集合オブジェクトに存在する場合にどのインターフェイスを検索しそしてそれらをいかに組み合わせて呼び出すかの判断を変更するためのメソッドを提供する。
【００８５】
好ましい実施例において、動的な集合は、マルチタイプオブジェクトを用いて実施される。マルチタイプオブジェクトとは、種々のタイプのオブジェクト、ひいては、その名前を集合することのできるオブジェクトをいう。集合できるようにコード化されたインターフェイスのみをマルチタイプオブジェクト内に囲むことができる。（即ち、例えば、このようなインターフェイスは、インターフェイス及び参照カウント要求を、囲んでいるオブジェクトへ送ることができる。）マルチタイプオブジェクトは、特定のインターフェイス又はオブジェクトの集合を要求すると共に、要求されたインターフェイスをいかに呼び出すかを判断するためのルールを追加するIMultitypeインターフェイスを与える。以下のコード表７は、IMultitypeインターフェイスの好ましい定義のための擬似コードを含んでいる。
0004322967.tif 000021
【００８６】
図８、９、１０は、マルチタイプオブジェクトに２つのオブジェクトを追加するシーケンスのブロック図である。図８は、マルチタイプオブジェクトのインスタンスを示すブロック図である。オブジェクトＭＴＯ  ７Ａ０１は、提示されたインターフェイスであるIMultitypeインターフェイスＭＴ及び制御IUnknownを実行する。マルチタイプオブジェクトに外部インターフェイスが追加されるときには、マルチタイプオブジェクトが集合オブジェクトとなる。マルチタイプオブジェクトの実現部は、それが集合に追加したインターフェイスのリスト７Ａ０２、７Ａ０９及び７Ａ１０を含んでいる。マルチタイプオブジェクトは、これらのリストを用いて、マルチタイプオブジェクトの制御IUnknownインターフェイスによりその囲まれた集合オブジェクトの種々のインターフェイスを呼び出す。又、マルチタイプオブジェクトは、インターフェイスリスト７Ａ０２、７Ａ０９及び７Ａ１０からインターフェイスをアクセスしそして組み合わせるためのルールのリスト７Ａ１１も含んでいる。
【００８７】
これらの異なるリストの相互作用により、マルチタイプオブジェクトの強力な能力が与えられる。AddRule メソッドを用いて固定又は指定することができるルール７Ａ１１のリストは、特定のインターフェイスに対する異なるインターフェイスリストの相互作用及び使用を指定する。従って、他のルールを選択するためのルールと、特定のインターフェイスを選択して組み合わせるためのルールとが存在する。３つの異なるインターフェイスリスト７Ａ０２、７Ａ０９及び７Ａ１０は、オーバーライド、増強、デフォールト及び制御能力を支援するために設けられている。マルチタイプオブジェクトにインターフェイスが追加されるときには、集合を形成するクライエントプログラムが、インターフェイスの追加に使用すべきリストを指定する。リスト７Ａ０２は通常のリストを構成し、リスト７Ａ０９はデフォールトリストを構成し、そしてリスト７Ａ１０はオーバーライドリストを構成する。基本的に、オーバーライドリストは、通常のリスト上のインターフェイスの前にアクセスする必要のあるインターフェイスを指すことによりオーバーライド及び制御能力を実行するよう意図される。デフォールトリストは、オーバーライドリスト及び通常リストが要求されたインターフェイスを含まないときだけアクセスされるインターフェイスを指示するように意図される。これらのリストの相互作用については、IRule インターフェイスの説明において詳細に述べる。
【００８８】
図９は、AddObject メソッドを用いてIBasicインターフェイスを集合した後のマルチタイプオブジェクトＭＴＯを示すブロック図である。AddObject メソッドは、指定されたオブジェクトの全てのインターフェイスをマルチタイプオブジェクトに追加する。集合オブジェクトＭＴＯ  ７Ｂ０１は、図８を参照して述べたマルチタイプインターフェイスと、囲まれたスプレッドシートオブジェクトＳ１７Ｂ０４とを備えている。囲まれたオブジェクトＳ１は、外部インターフェイスIBasic (B)のインスタンスと、外部インターフェイスIPrint (P)のインスタンスと、IUnknownのインスタンスとを実行する。（外部インターフェイスとは、囲んでいるオブジェクトによって提示されるオブジェクトのインターフェイスである。内部インターフェイスとは、囲んでいるオブジェクトによって提示されないオブジェクトのインターフェイスである。）囲まれたオブジェクトＳ１がマルチタイプオブジェクトＭＴＯの通常のリストに追加されたときには、集合されたインターフェイス７Ｂ０２の通常のリストが、囲まれたオブジェクトＳ１のIUnknownインターフェイスを識別する単一エレメント７Ｂ０３を含む。Ｓ１のIUnknownインターフェイスは、要求があったときに外部インターフェイスＢ及びＰにポインタを返送する。Ｓ１は集合可能であるから、Ｓ１が具体化されるときには、これがポインタ７Ｂ０５を、囲んでいるオブジェクトＭＴＯへ通し、これは、オブジェクトＭＴＯの一部として集合された他のインターフェイスをアクセスするために後で使用することができる。
【００８９】
図１０は、AddObject メソッドを用いてIDatabase インターフェイスを追加した後の結果のマルチタイプオブジェクトＭＴＯを示すブロック図である。この点において、集合オブジェクトＭＴＯ  ７Ｃ０１は、図８について述べたIMultitypeインターフェイスと、図９について述べた囲まれたスプレッドシートオブジェクトＳ１と、データベース能力を実行する囲まれたデータベースオブジェクトＳ２  ７Ｃ０７とを備えている。囲まれたオブジェクトＳ２は、外部インターフェイスIDatabase (D) のインスタンスと、IUnknownのインターフェイスとを実行する。IMultitypeインターフェイスのAddObject メソッドを用いてマルチタイプオブジェクトＭＴＯに囲まれたオブジェクトＳ２が追加されたときには、集合されたインターフェイス７Ｃ０２の通常のリストは、２つのエレメント７Ｃ０３及び７Ｃ０６を含む。エレメント７Ｃ０６は、囲まれたオブジェクトＳ２のIUnknownインターフェイスを識別する。Ｓ１と同様に、Ｓ２のIUnknownインターフェイスは、外部インターフェイスＤに対するポインタを返送することができ、囲んでいるオブジェクトＭＴＯに対するポインタ７Ｃ０８を他のＭＴＯインターフェイスへのアクセスのために含んでいる。
【００９０】
追加されたインターフェイス及びオブジェクトを追跡するのに使用されるデータ構造体の多数の他の実施例が考えられることが当業者に明らかであろう。例えば、使用するリストの数及び種類を変更することができる。特に、１つのリストしかもたないようにすることもできるし、オーバーライド又はデフォールトリストを任意に形成することもできる。又、全オブジェクトが集合されるときには、各リストエレメントが集合されるべき正確なインターフェイスのみを指示し、IUnknownのオブジェクトは指示しないようにすることもできる（AddInterface型のマルチタイプオブジェクトのみをサポートする）。或いは又、どのインターフェイスが集合に追加されるかに係わりなく、各リストエレメントがIUnknownのオブジェクトを指すことを必要とすることもできる（AddObject 型のマルチタイプオブジェクトのみをサポートする）。更に、インターフェイス識別子の種々の記憶されたリスト又はハッシュテーブルを含む他のリスト実現を使用することもできる。
0004322967.tif 000022
0004322967.tif 000023
0004322967.tif 000024
0004322967.tif 000025
【００９１】
コード表８は、図８ないし１０のオブジェクトＳ１の好ましいクラス定義に対するＣ＋＋擬似コードを含み、これは、Ｓ１オブジェクトのインスタンスを形成するグローバルな関数と共に集合（集合オブジェクト）内に囲むことのできるものである。クラスIUnknown、IBasic及びIPrintは、Ｓ１を構成する各インターフェイスのメソッドを定義するインターフェイスである。クラスＳ１は、IUnknownインターフェイス、IBasicインターフェイス及びIPrintインターフェイスを実施する。IBasic及びIPrintインターフェイスは、外部インターフェイスとして実施される。
【００９２】
図１１は、クラスＳ１のオブジェクトのインスタンスのデータ構造レイアウトのブロック図である。インスタンス構造８０１は、クラスＳ１(m B 、m  P 、m  punkOuter)のデータメンバと、仮想関数表ポインタ(S1::vfptr) とを含んでいる。データメンバm  B 及びm  P は、各々、クラスＢ及びＰのオブジェクトのインスタンスである（これらは、インターフェイスIBasic及びIPrintのクラス実施である）。データメンバm  B 及びm  P はクラスＳ１のフレンドであり、m  B 及びm  P オブジェクトがm  punkOuter のようなクラスＳ１のプライベートメンバにアクセスできるようにする。仮想関数表ポインタS1::vfptr は仮想関数表８０２を指し、データメンバm  B 内の仮想関数表ポインタS1::B::vfptrは仮想関数表８０３を指し、データメンバm  P 内の仮想関数表ポインタS1::P::vfptrは仮想関数表８０４を指す。仮想関数表８０２は、制御IUnknownインターフェイスに対して定義された仮想関数（メソッド）のポインタを含み、仮想関数表８０３は、IBasicインターフェイスに対して定義された仮想関数のポインタを含み、そして仮想関数表８０４は、IPrintインターフェイスに対して定義された仮想関数のポインタを含む。メソッド８０５ないし８０９は、クラスＳ１の関数メンバである。メソッド８０８はクラスＳ１の構成子である。メソッド８０９はクラスＳ１のCreateInstanceメソッドである。メソッド８１０ないし８１８はクラスＢの関数メンバである。メソッド８１３はクラスＢの構成子である。メソッド８１９ないし８２３はクラスＰの関数メンバである。メソッド８２３はクラスＰの構成子である。図１１は、集合の部分ではないＳ１オブジェクトのインスタンスを示しているので、データメンバS1::B::m pS1 、S1::P::m pS1 及びS1::m  punkOuter(囲んでいるオブジェクトに対するポインタ）は、Ｓ１オブジェクト自体を指すように初期化される。
【００９３】
コード表８によって定義されたオブジェクトＳ１は、静的な集合を参照して述べた集合オブジェクトの要件に合致する。動的な集合を行う目的で、コード表８は、Ｓ１をその囲んでいるオブジェクトとその集合時にいかに自動的に通信できるか及び関数S1::QueryInterfaceから何が返送されるかを示している。より詳細には、Ｓ１オブジェクトの形成時に、囲んでいるマルチタイプオブジェクトの制御IUnknownインターフェイスのポインタがメソッドCreateInstanceへ通される。このポインタは、次いで、Ｓ１の外部インターフェイス（IBasic及びIPrint）のメソッドQueryInterfaceによって使用され、インターフェイス要求をその囲んでいるマルチタイプオブジェクトへルート指定する。Ｓ１インターフェイスがその閉じているマルチタイプオブジェクトから要求されたときには、その閉じているマルチタイプオブジェクトの制御IUnknownのメソッドQueryInterfaceがメソッドS1::QueryInterfaceを呼び出し、これは、インターフェイスIBasic、インターフェイスIPrint又はインターフェイスIUnknownの適当なインスタンスに対するポインタを返送し、そしてＳ１オブジェクトの参照カウントを適宜に増加する。（S1::QueryInterfaceを呼び出すために囲んでいるマルチタイプオブジェクトによって使用されるメカニズムは、以下で詳細に説明する。）
【００９４】
当業者であれば、囲んでいるマルチタイプオブジェクトの制御IUnknownインターフェイスのポインタを集合オブジェクトへ通すために多数の別の態様が存在することが明らかであろう。例えば、形成時にポインタを通すのではなく、特に、このポインタを通すためのメソッドを定義することができる。この実施例を用いる場合に、オブジェクトは、いったん集合されると、後で集合解除することもできるし、或いはオブジェクトを後で異なる囲み込みオブジェクトへ集合することができる。
【００９５】
コード表８が図８ないし１０に示したようにマルチタイプオブジェクトといかに相互作用するかを理解するために、クライエント要求がなされるときのコールシーケンスについて調べるのが有用であろう。以下のコード表９は、クライエントがマルチタイプオブジェクトＭＴＯのポインタを有するときにクライエントアプリケーションがIBasicインターフェイスを要求するときの図８に対応するコールの擬似コードシーケンスを示している。
コード表９
MTO::QueryInterface(IID  Ibasic, ppv)
これは、IBasicインターフェイスをサポートする集合されたオブジェクトを見つける。
S1::IUnknown::QueryInterface(IID IBasic,ppv)
これは、B インターフェイスにポインタを返送する。
第１のコール(MTO::QueryInterface) において、ＭＴＯは、集合されたインターフェイスのリストから、どのオブジェクトのQueryInterfaceメソッドを呼び出すかを決定し、次いで、第２のコール(S1::IUnknown::QueryInterface)においてそれを呼び出す。
【００９６】
コード表１０は、クライエントアプリケーションが、囲んでいるマルチタイプオブジェクトのポインタではなくて、囲まれたオブジェクトのインターフェイス（Ｓ１のIPrintインターフェイスのような）の１つに対するポインタを有する場合に、コールの擬似コードシーケンスがいかに変化するかを示している。
コード表１０
P::QueryInterface(IID  IBasic,ppv)
これは、囲んでいるオブジェクトにコールを送る。
MTO::IUnknown::QueryInterface(IID  IBasic,ppv)
//m  punkOuter はMTO::IUnknown を指す。
これは、IBasicインターフェイスをサポートする集合されたオブジェクトを見つける。
S1::IUnknown::QueryInterface(IID IBasic,ppv)
これは、B インターフェイスにポインタを返送する。
コード表１０は、集合がその囲んでいるオブジェクトへいかに自動的に要求を送ってその集合内の他のインターフェイスをアクセスするかを示すものである。この場合に、囲まれたオブジェクトのQueryInterface関数は、囲んでいるオブジェクト（ＭＴＯ）のQueryInterfaceメソッドへ要求を送る。次いで、MTO::QueryInterface メソッドは、コード表９のように機能する。
【００９７】
IDatabase インターフェイスを実行するＳ２オブジェクトは、上記したＳ１オブジェクトと同様である。
0004322967.tif 000026
0004322967.tif 000027
0004322967.tif 000028
0004322967.tif 000029
0004322967.tif 000030
【００９８】
コード表１１は、インターフェイスを動的に集合するのに使用できるマルチタイプオブジェクトの好ましいクラス定義に対するＣ＋＋擬似コードである。クラスＭＴＯは、マルチタイプオブジェクトに対しIMultitypeインターフェイス及び制御IUnknownインターフェイスのインスタンスを実行する。
【００９９】
グローバルな関数CreateInstanceMTO は、クラスＭＴＯのオブジェクトのインスタンスを形成する。クライエントはこの関数を呼び出し、クラスＭＴＯのオブジェクトを具体化する。この関数を用いて、クライエントは、コンパイル時間又はランタイムにＭＴＯクラス定義をアクセスすることなくクラスＭＴＯのオブジェクトを具体化することができる。関数CreateInstanceMTO には、具体化されたＭＴＯオブジェクトが別のオブジェクト内に集合されたときに制御IUnknownインターフェイス(punkOuter) に対するポインタが通される。この関数は、パラメータpunkOuter に沿って通されるメソッドMTO::CreateInstance を呼び出す。
【０１００】
メソッドMTO::CreateInstance は、ＭＴＯオブジェクトを具体化し、ＭＴＯオブジェクトのIUnknownインターフェイスに対するポインタ(ppunk) を返送する。このインターフェイスは、次いで、関数CreateInstanceMTO によって使用され、クライエントアプリケーションにより実際に要求されたインターフェイスを返送することができる。メソッドMTO::CreateInterfaceは、新たな演算子を使用してＭＴＯオブジェクトを具体化する。具体化の間に、構成子MTO::MTOが呼び出されそしてパラメータpunkOuter の値が通される。
【０１０１】
構成子MTO::MTOは、データメンバ m MT及び m punkOuter を初期化する。クラスＭＴのデータメンバ m MTの具体化の間に、構成子MT::MTが呼び出され、ＭＴＯオブジェクトに対するこのポインタが通される。（Ｃ＋＋において、このポインタは、オブジェクトのインスタンスそれ自体を指す。）構成子MT::MTは、次いで、ＭＴＯクラスを再び指すようにローカル変数をセットする。構成子MTO::MTOには、パラメータpunkOuter が通される。punkOuter の値がナルの場合には、構成子MTO::MTOは、新たに具体化されたＭＴＯオブジェクトを指すようにデータメンバ m punkOuter をセットする。他方、punkOuter がナルでない場合、例えば、オブジェクトが大きな集合の一部として集合された場合は、構成子MTO::MTIO は、データメンバ m punkOuter をパラメータpunkOuter の値にセットする。即ち、データメンバ m punkOuter は、ＭＴＯオブジェクトが囲まれたときには集合の制御IUnknownインターフェイスの値を指し、そしてＭＴＯオブジェクトが囲まれないときにはＭＴＯオブジェクトのIUnknownインターフェイスを指す。
【０１０２】
ＭＴＯオブジェクトによって実行されるIMultitypeインターフェイスは、４つのメソッドAddObject 、AddInterface、AddRule 及びEnumを含んでいる。メソッドAddObject は、マルチタイプオブジェクト内に囲まれるべきオブジェクトを追加するという役割を果たす（全てのオブジェクトインターフェイスはアクセス可能とされる）。これは、図１２を参照して説明する。メソッドAddInterfaceは、マルチタイプオブジェクトに単一のインターフェイスインスタンスを追加する役目を果たす。メソッドAddInterfaceはメソッドAddObject に関連して説明する。メソッドAddRule は、クライエントアプリケーションが特定のインターフェイス識別子を要求するときに問い合わせすべきオブジェクト又は返送すべきインターフェイスのどの組み合わせかを決定するのに使用される組み合わせルールをクライエントアプリケーションが指定できるようにする。これは、ルールオブジェクトに関連して詳細に説明する。メソッドEnumは、マルチタイプオブジェクトによって維持される種々のインターフェイスリストを列挙するためにルールオブジェクトによって使用される。このメソッドは、ルールオブジェクトに関連して詳細に説明する。
【０１０３】
図１２は、マルチタイプオブジェクトによって実行されるIMultitypeインターフェイスのメソッドAddObject の流れ線図である。図１２は、コード表１１に示されたAddObject のコードに対応する。メソッドAddObject は、オブジェクトの全てのインターフェイスへのマルチタイプオブジェクトアクセスに動的に追加するようにクライエントアプリケーションにより使用される。このメソッドには、どのリストにオブジェクトを追加するかを指示するリスト指示子と、オブジェクトを指定のリストのヘッド又はテイルに追加しなければならないかどうかの指示と、集合すべきオブジェクトのIUnknownインターフェイスに対するポインタとが通される。このメソッドは、メソッドAddInterfaceと共に、マルチタイプオブジェクトによって囲まれるオブジェクト及びインターフェイスに関する情報を維持するための構造を実施する。
【０１０４】
１つの典型的な実施は、囲まれたオブジェクトのインターフェイスを各々指すエレメントで形成されたリスト構造を使用する。全オブジェクトを囲むためにメソッドAddObject が呼び出されたときには、指定のリスト構造に新たなエレメントが追加され、新たなエレメントは、囲まれたオブジェクトのIUnknownインターフェイスを指す。このIUnknownインターフェイスは、次いで、囲まれたオブジェクトの成分インターフェイスをアクセスするのに使用することができる。一方、オブジェクトの単一インターフェイスを囲むためにメソッドAddInterfaceが呼び出された場合には、指定のリスト構造に新たなリストエレメントが追加され、この新たなエレメントは、この単一インターフェイスに直接アクセスできるようにこの単一インターフェイスを指す。典型的な実施において、各リストエレメントは、インターフェイス識別子によって指示され、囲まれたオブジェクトのインターフェイスを指し、そしてそのリスト内の次のエレメントを指す。クライエントはリストのヘッド又はテイルのいずれかに追加できるので、二重にリンクされたリストを用いて効率を上げることができる。
【０１０５】
メソッドinvocation（呼び出し）において、クライエントアプリケーションはアプリケーションが指定のインターフェイス又はオブジェクトを追加したいのはどのリストかを指定する。「通常」リストは、クライエントアプリケーションがインターフェイス又はオブジェクトを集合に単に追加しようとするときに用いられる。「オーバーライド」リスト及び「デフォールト」リストは、クライエントアプリケーションがインターフェイスを追加しようとし、そのメソッドが通常リストにおけるものとは異なる時間に呼び出されるときに、使用される。典型的な実施においては、特定のインターフェイスが要求されたときに、マルチタイプオブジェクトの制御IUnknownのメソッドQueryInterfaceは、要求されたインターフェイスサーチリストを、最初にオーバーライドリストを介して、第２に通常リストを介してそして第３にデフォールトリストを介して返送する。当業者であれば、リスト構造の番号を変え、サーチ順序を変えそして要求されたインターフェイスとの一致を何が構成するかの判断を変えることを含む多数の他の実施及びサーチ戦略が明らかであろう。以下に述べる好ましい実施例では、クライエントアプリケーションは、決定ルールを変更する。
【０１０６】
図１２のステップは、指定のリストにエレメントをいかに追加するかを示している。ステップ９０１において、このメソッドは新たなリスト項目を割り当て、そしてステップ９０２においてその項目を初期化して、クライエントアプリケーションが集合しようとするインターフェイスを含むオブジェクトのIUnknownインターフェイスを指すと共に、その項目のインターフェイス識別子を含むようにする（IUnknownインターフェイスを指示するために）。ステップ９０３において、このメソッドは、通常リストが指定されたかどうか判断する。もしそうならば、このメソッドはステップ９０４に続き、さもなくば、ステップ９０７に続く。ステップ９０４において、このメソッドは、クライエントアプリケーションが通常リストのヘッドにエレメントを挿入しようとしているかどうかを判断する。もしそうならば、メソッドはステップ９０５に続き、さもなくば、ステップ９０６に続く。ステップ９０５では、このメソッドは、初期化されたエレメントを通常リストのヘッドに挿入し、そして復帰する。ステップ９０６では、初期化されたエレメントを通常リストのテイルに挿入しそして復帰する。ステップ９０７ないし９１４は、オーバーライド及びデフォールトリストについて同様に作用する。
【０１０７】
IMultitypeインターフェイスのメソッドAddInterfaceは、メソッドAddObject と同様に機能する。その主たる相違は、追加されたリストエレメントが、囲まれるべきオブジェクトの指定のIUnknownインターフェイスを指すのではなくて、追加されたリストエレメントが指定のインターフェイスを指しそして通されたインターフェイス識別子を指示する。このように、オブジェクトの単一の単一インターフェイスを、他のインターフェイスを提示せずに、集合することができる。
【０１０８】
コード表１１に戻ると、IMultitypeインターフェイス（継承されたIUnknownインターフェイス）のメソッドQueryInterface、AddRef及びRelease は、このIMultitypeインターフェイスを実施する親オブジェクト（ＭＴＯ）のIUnknownインターフェイスに要求を送る。
【０１０９】
ＭＴＯオブジェクトにより実施される制御IUnknownインターフェイスは、メソッドQueryInterface、AddRef及びRelease を含む。メソッドAddRef及びRelease は、マルチタイプオブジェクトの参照カウントを実行する。参照カウントがゼロのときには、ＭＴＯオブジェクトが削除される。
【０１１０】
図１３は、マルチタイプオブジェクトに対する制御IUnknownインターフェイスのメソッドQueryInterfaceの流れ線図である。図１３は、コード表１１に示されたQueryInterfaceに対するコードに対応する。メソッドQueryInterfaceは、要求されたインターフェイスを、それ自身の実施についての知識と、集合されたインターフェイスリストからの情報とを用いて位置決めする。このメソッドは、要求されたインターフェイス識別子である入力パラメータを取り上げ、そして要求されたインターフェイスに対するポインタを出力する。ステップ１００１ないし１００４において、このメソッドは、要求されたインターフェイスがマルチタイプオブジェクト自体によって実施されたものであるかどうかを判断する。さもなくば、ステップ１００５ないし１０１４において、このメソッドは、要求されたインターフェイスを見つけるまで、各々の囲まれたオブジェクト又はインターフェイスをサーチする。
【０１１１】
ステップ１００１において、このメソッドは、要求されたインターフェイス識別子がIID  IMultitypeに等価であるかどうかを決定し、もしそうであれば、ステップ１００２に続き、さもなくば、ステップ１００３に続く。ステップ１００２では、このメソッドは、オブジェクトＭＴＯにより実施されたIMultitypeのインスタンスを指すように出力パラメータをセットし、そして復帰する。ステップ１００３では、このメソッドは、要求されたインターフェイス識別子がIID  IUnknownに等価であるかどうかを決定し、もしそうであれば、ステップ１００４に続き、さもなくば、ステップ１００５に続く。ステップ１００４では、このメソッドは、マルチタイプオブジェクトによって実施されるIUnknownのインスタンスであるこのポインタに出力パラメータをセットし、そして復帰する。
【０１１２】
ステップ１００５ないし１０１４では、このメソッドは、要求されたインターフェイスに一致するインターフェイスを指す第１のリストエレメントをサーチするように３つのリストをループする。このインスタンスが見つかったときには、それがパラメータppv において返送され、そしてこのメソッドは首尾良い状態を返送する。この実施は、使用できる多数の形式のサーチの一例に過ぎないことが当業者に明らかであろう。ステップ１００５において、一時的なリスト指示子はマルチタイプオブジェクトによって実施されるリストの組からの次のリストにセットされる。好ましい実施例において、このリストの組は、オーバーライド、通常、及びデフォールトリストを含む。ステップ１００６において、このメソッドは、現在リストの前部を指すように一時的な変数項目をセットする。ステップ１００７において、このメソッドは、現在リスト内の全てのエレメントを排出しそして一致インスタンスがまだ見つからないかどうかを決定する。このメソッドが現在リストの終わりに達した場合には、この方法はステップ１００８に続き、さもなくば、ステップ１００９に続く。ステップ１００８において、このメソッドは、更に多くのリストがサーチに使用できることを決定すると、ステップ１００５に戻って、新たなリストのサーチを開始する。さもなくば、このメソッドは、一致するインターフェイスが見つからないので、不首尾の状態を返送する。ステップ１００９において、このメソッドは、一時的な変数pitem によって指された現在リストエレメントがIUnknownインターフェイスを指すかどうか決定し、もしそうならば、ステップ１０１０へ続き、さもなくば、ステップ１０１３へ続く。（現在リストエレメントがIUnknownインターフェイスを指す場合には、このインターフェイスに対応するオブジェクトは、一致インターフェイスのために更に問い合わせされる必要がある。）ステップ１０１０において、このメソッドは、現在リストエレメントによって指されたIUnknownインターフェイスのメソッドQueryInterfaceを呼び出す。ステップ１０１１において、このメソッドは、要求されたインターフェイス識別子が見つかったかどうか決定し、もしそうでなければ、ステップ１０１２へ続き、さもなくば、復帰する。要求されたインターフェイス識別子が見つからない場合には、QueryInterfaceコールが、返送パラメータppv を、要求されたインターフェイスを指すように既にセットしている。この場合にこのメソッドは、首尾良い状態を返送する。さもなくば、ステップ１０１２において、このメソッドは、リスト内の次のエレメントを指すように現在リストエレメントポインタ(pitem) をインクレメントし、そしてステップ１００７に続き、現在リスト構造を通してサーチする。ステップ１０１３において、このメソッドは、要求されたインターフェイス識別子を、現在リストエレメントのインターフェイス識別フィールドと比較し、それらが同じであれば、ステップ１０１４へ続き、さもなくば、サーチを伴うステップ１０１２へ続く。ステップ１０１４ではこのメソッドは、返送パラメータppv を、要求されたインターフェイスを（現在リストエレメントにより指された）指すようにセットし、そして首尾良い状態を復帰する。
【０１１３】
図１４は、IBasic、IPrint及びIDatabase インターフェイスがメソッドAddObject を用いて動的に集合された後の図１０に対応するマルチタイプオブジェクトのデータ構造レイアウトを示すブロック図である。データ構造レイアウトは、インスタンスデータ１１０１、仮想関数表１１０４及び１１０５、メソッド１１０７ないし１１１５、並びに現在囲まれている（集合されたオブジェクト）のインスタンスを備えている。インスタンスデータ１１０１は、制御IUnknownインターフェイスに対する仮想関数表のポインタと、クラスＭＴのインスタンス（IMultitypeインターフェイスの実施）であるデータメンバ m MTと、ＭＴＯオブジェクトのIUnknownインターフェイスを指すデータメンバ m punkOuter と、現在追加されたインターフェイスの通常リストのヘッドを指すデータメンバ m pnormal  itemheadとを含んでいる。図示されたように、リストは現在２つのエレメントを含んでいる。リストエレメント１１０２は、Ｓ１オブジェクト８０１ないし８２３（図１１で定義された）を指し、そしてリストエレメント１１０３は、Ｓ２オブジェクト１１０６のインスタンスを指す。図示されていないが、マルチプルオブジェクトは、空のデフォールトリスト及びオーバーライドリストに対するポインタも指す。
【０１１４】
囲まれたＳ１オブジェクトが具体化されるときには、そのデータメンバS1:: m punkOuter が、ＭＴＯオブジェクトのIUnknownインターフェイスを指すように初期化される。同様に、囲まれたＳ２オブジェクトが具体化されるときには、そのデータメンバS2:: m punkOuter が、ＭＴＯオブジェクトのIUnknownインターフェイスを指すように初期化される。このタスクは、上記のように、CreateInstanceXX関数（但し、ＸＸはＳ１又はＳ２）におけるＭＴＯのポインタを通すことによって行われる。
コード表１２
MTO    *pMTO;
IMultiType*my  pMT;
IUnknown*pSpreadSheet,*pDataBase;
CreateInstanceMTO(NULL,IID IUnknown,pMTO);
CreateInstanceS1(pMTO,IID  IUnknown,pSpreadSheet);
CreateInstanceS2(pMTO,IID  IUnknown,pDataBase);
pMTO->QueryInterface(IID Multitype,my pMT);
my pMT->AddObject(IID ISpreadSheet,NORMAL  LIST,true,pSpreadSheet)
my pMT->AddObject(IID IDataBase,NORMAL LIST,true,pDataBase);
...
//ある時間の後に、他のあるクライエントがスプレッドシートオブジェクトのデ//ータベース能力を呼び出すことができる。
pSpreadSheet->QueryInterface(IID IDaraBase,ppv);
ppv->Data();
【０１１５】
コード表１２は、１組のインターフェイスを動的に集合するためのステップの好ましいリストに対する擬似コードを含んでいる。この例は、オブジェクトの全てのインターフェイスを追加するためのメソッドAddObject を用いて図１０に示すIBasic、IPrint及びIDatabase のインスタンスを追加することに対応する。第１に、関数CreateInstanceMTO を用いて新たなマルチタイプオブジェクトが割り当てられる。この関数を用いると、IUnknownインターフェイスが、新たに具体化されたマルチタイプオブジェクトに対し検索される。このインターフェイスは、Ｓ１及びＳ２オブジェクトが、囲んでいるマルチタイプオブジェクトをアクセスできるように具体化されたときにこれらＳ１及びＳ２オブジェクトに通される。ある点において、Ｓ１オブジェクトのインスタンスが形成され、マルチタイプオブジェクトに対するポインタがそこに通される。又、Ｓ２データベースオブジェクトのインスタンスが形成され、マルチタイプオブジェクトに対するポインタがそこに通される。Ｓ１及びＳ２のインスタンスが形成された後に、IMultitypeインターフェイスがマルチタイプオブジェクトから検索される。このインターフェイスは、スプレッドシート及びデータベースインターフェイスをマルチタイプオブジェクトに動的に追加するのに使用される。次いで、マルチタイプオブジェクトのIMultitypeインターフェイスのメソッドAddObject が呼び出されて、Ｓ１及びＳ２オブジェクトがマルチタイプオブジェクトへと集合される。これらのオブジェクトがマルチタイプオブジェクトに囲まれると、マルチタイプオブジェクトのいずれかのインターフェイス又はその囲まれたオブジェクトのいずれかを用いて、集合オブジェクト内の他のインターフェイスをアクセスすることができる。コード表２は、基本的なスプレッドシートオブジェクト（Ｓ１）を用いてデータベースインターフェイスを検索しそしてこのIDatabase インターフェイスのデータメソッドを呼び出すという例を示している。
0004322967.tif 000031
0004322967.tif 000032
0004322967.tif 000033
0004322967.tif 000034
0004322967.tif 000035
0004322967.tif 000036
0004322967.tif 000037
0004322967.tif 000038
0004322967.tif 000039
0004322967.tif 000040
0004322967.tif 000041
【０１１６】
コード表１３は、ルールオブジェクトのリストをサポートするために増強されたマルチタイプオブジェクトに対する好ましいクラス定義のＣ＋＋擬似コードを含んでいる。これらのルールオブジェクトは、マルチタイプオブジェクトの要求されたインターフェイスを組み合わせるための組み合わせルール、又はルールオブジェクトのリストからルールオブジェクト（組み合わせルールを含む）を選択するための選択ルールのいずれかを含むことができることを想起されたい。各ルールオブジェクトは、ルールオブジェクトをマルチタイプオブジェクトにフックするためのIRule インターフェイスのインスタンスを実行する。又、各ルールオブジェクトは、ルールオブジェクトが組み合わせルールを与えるところのインターフェイスのインスタンスも実行する。例えば、全ての囲まれた集合されたオブジェクトのプリントを整合するために、IPrintインターフェイスの組み合わせルールを実施するルールオブジェクトを設けることができる。このようなルールオブジェクトは、IRule インターフェイスの実施と、IPrintインターフェイスの実施とを含む。この特定例は、コード表１４を参照して以下に詳細に述べる。
【０１１７】
又、コード表１３は、ルールオブジェクトのリストからルールオブジェクトを選択する選択ルールを含むルールオブジェクトに対する好ましいクラス定義のＣ＋＋擬似コードも示している。簡単な例にするために、このルールオブジェクトによって与えられるルールは、ルールオブジェクトのリスト（MTO::QueryInterface により定められた）からルールオブジェクトをアクセスするためにマルチタイプオブジェクトによって使用されるデフォールトコードに類似している。しかしながら、この選択ルールオブジェクトは、ルールオブジェクトをアクセスするためのいかなるルールも実施できることが当業者に明らかであろう。
【０１１８】
コード表１３に示すように、マルチタイプオブジェクトは、２つのインターフェイスIMultitype及びIUnknownを実行する。これらのインターフェイスは、以下に述べるものを除いて、コード表１１に示したものと本質的に同じである。コード表１３に示されたコード表１１からの基本的な変更は、制御IUnknownのメソッドQueryInterface(MTO::QueryInterface) が、固定の１組のルールに基づき一致インターフェイスに対して囲まれたインターフェイスの３つのリストをもはやサーチしないことである。（図１４に示された固定のルールは、オーバーライド、通常及びデフォールトリストから最初に見つかったインターフェイスをその順序で返送することである。）むしろ、ＭＴＯオブジェクト自体によって実施されないインターフェイスが要求されたと決定されると、MTO::QueryInterface は、その要求されたインターフェイスに対応するルールオブジェクトがルールオブジェクトのＭＴＯオブジェクトリストに存在する場合はそこまで要求を延期する。見つかったルールオブジェクトは、次いで、要求されたインターフェイスの実施を与えるか又は集合されたインターフェイスのＭＴＯオブジェクトの３つのリストからインターフェイスを返送する役割を果たす。従って、クライエントアプリケーションは、特定のインターフェイスを検索するか又は組み合わせるそれ自身のルールオブジェクトを設けることにより、集合されたオブジェクトの制御IUnknownのメソッドQueryInterfaceの動作を変更することができる。これらのルールオブジェクトは、マルチタイプオブジェクトの実施とは独立して実施できる。というのは、それらは、囲まれたインターフェイス及びルールリストをアクセスするためにマルチタイプオブジェクトによって与えられたパブリック・エニュメレーションメソッドを使用できるからである。更に、クライエントアプリケーションは、IUnknownインターフェイスに対するルールオブジェクトを設けることにより要求されたインターフェイスに対応するルールオブジェクトを見つけるためにMTO::QueryInterface により使用される選択ルールを変更することができる。
【０１１９】
コード表１１を参照して既に述べたメソッドAddObject 及びAddInterfaceに加えて、クラスＭＴＯは、ルールオブジェクトを取り扱うための２つのメソッド、AddRule 及びEnumを与える。メソッドAddRule は、AddInterfaceと同様に実行される。メソッドAddRule は、ルールオブジェクトのリストに対して新たなリスト項目を形成し、そして入力パラメータとして通されたルールオブジェクトのインターフェイス識別子及びIRule インターフェイスを指すようにこの項目を初期化する。このメソッドは、次いで、ルールオブジェクトのリストに新たなリスト項目を挿入し、そしてその新たなリスト項目により指されたIRule インターフェイスのメソッドInitを呼び出し、ＭＴＯオブジェクトに戻るルールオブジェクトアクセスを与える。このようなアクセスは、インターフェイスの他のリストをアクセスするためのメソッドEnumを呼び出すようにルールオブジェクトによって使用される。
【０１２０】
図示されたように、メソッドAddRule は、ルールオブジェクトのリストの終わりに新たなルールオブジェクトを追加する。更に、ルールオブジェクトのリストを使用するQueryInterfaceメソッドは、インターフェイス識別子当たりルールオブジェクトが１つしかないと（又は最初に見つかった１つが有効であると）仮定する。それ故、あるエラーチェック又は順序制御が好ましく実行される。他の囲まれたインターフェイスのリストと同様に、新たなルールオブジェクトは、リストのヘッド又はテイルのいずれかに挿入することができる。又、メソッドAddRule は、AddObject 及びAddInterfaceと同様に新たなルールオブジェクトをどこに追加するかを指示するパラメータを通すように変更することができる。或いは、他のリスト項目と同一にルールリスト項目を実施することができ、そしてメソッドAddInterfaceは、ルールオブジェクトをルールオブジェクトのリストに挿入するのに使用できる。多数の他の技術も考えられ、そして抽象的な意味では、ルールオブジェクトも動的に集合されたオブジェクトであることが当業者に明らかであろう。
【０１２１】
クラスＭＴＯは、指定のインターフェイスをサーチしそして検索するメソッドEnumを与える。ルールを組み合わせるためのルールオブジェクトは、このメソッドを使用して、３つの集合されたインターフェイスリストからインターフェイスを検索することができる。更に、組み合わせルールを選択するためのルールオブジェクトは、このメソッドを用いて、ルールオブジェクトのリストからルールオブジェクトIRule インターフェイスを検索することができる。図示されたように、メソッドEnumは、指定のリストから要求されたインターフェイス識別子に一致するインターフェイスの第ｉ番目の発生を返送する。このメソッドは、呼び出しにおいて指定されたリストのヘッド又はテイルからスタートする。別の実施例では、列挙されるリスト当たり１つづつの４つの個別のメソッドとして列挙子が実施される。
【０１２２】
通常、デフォールト及びオーバーライドリストに対し、メソッドEnumは、要求されたインターフェイス識別子を見つけるか又はリスト内の項目が尽きるまで、指定のリストから各リスト項目を検査する。この検査中に、リスト項目が全オブジェクトを指す場合には、メソッドEnumは、リスト項目によって指されたオブジェクトのメソッドQueryInterfaceを呼び出し、要求されたインターフェイスを潜在的に検索しそして返送する。さもなくば、リスト項目がIUnknown以外のインターフェイスを指す場合には、リスト項目により指されるインターフェイス識別子が、要求されたインターフェイス識別子と直接比較され、それらが一致する場合に、リスト項目により指されたインターフェイスが返送される。リスト項目が、一致するインターフェイスを発生しなかった場合には、このメソッドは、指定のリストの残り部分をサーチしつづける。
【０１２３】
メソッドEnumは、ルールオブジェクトのリストからサーチしそして検索するための若干異なる動作を与える。要求されたインターフェイス識別子を返送するのではなく、このメソッドは、インターフェイス識別子を使用して、ルールオブジェクトのリストにおける一致する項目を見つけ、そして要求されたインターフェイス識別子に対応するルールオブジェクトのIRule インターフェイスのポインタを返送する。
【０１２４】
コード表１３において、囲んでいるＭＴＯオブジェクトのメソッドQueryInterfaceは、ルールオブジェクトのリストをサポートするように変更されている。このメソッドは、先ず、入力パラメータで要求されたインターフェイスがＭＴＯオブジェクト自体により実施されるかどうかを決定する。もしそうであれば、このメソッドは、このインターフェイスを返送する。さもなくば、このメソッドは、選択ルールがルールオブジェクトのリストに存在する場合にこれを検索して呼び出す。最後に、選択ルールが存在しない場合には、メソッドQueryInterfaceがデフォールト選択コードを与える。
【０１２５】
ルールオブジェクトは、IUnknownインターフェイス識別子のもとでルールオブジェクトにリストに追加される場合に選択ルールを与える。好ましくは、このインターフェイス識別子は、この目的のために指定される。１つの実施例においては、見つかった第１のこのようなルールオブジェクトが選択ルールとして検索される。もし存在する場合には、その検索された選択ルールは、組み合わせルールをサーチしそして検索する役目を果たし、或いは組み合わせルールが存在しない場合には、集合されたインターフェイスの３つのリストからインターフェイスをサーチしそして検索する。検索された選択ルールは、そのIUnknownインターフェイスに対してIUnknownインターフェイス識別子に対応するルールオブジェクトに問い合わせをし（IRule インターフェイスを用いて）そしてこの検索されたIUnknownインターフェイスのメソッドQueryInterfaceを呼び出すことにより、呼び出される。検索されたIUnknownインターフェイスは、ルールオブジェクトの制御IUnknownインターフェイスであることに注意されたい。
【０１２６】
選択ルールが存在しない場合には、メソッドMTO::QueryInterface は、デフォールト選択コードを与える。このデフォールト選択コードは、要求されたインターフェイスに対する組み合わせルールをそれが存在する場合に返送するか、又は通常リスト、オーバーライドリスト及びデフォールトリストから見つかった第１の一致するインターフェイスをその順序で返送する。（デフォールト選択コードは、組み合わせルールが存在しないときにメソッドMTO::QueryInterface と同様に動作する。）組み合わせルールを実施するルールオブジェクトは、要求されたインターフェイスの実行を与えるか、又は集合されたインターフェイスのＭＴＯオブジェクトの３つのリストからインターフェイスを返送する。
【０１２７】
例えば、コード表１３は、ルールオブジェクトのリストからルールオブジェクトを選択するための選択ルールを与えるルールオブジェクトの実施を示している。クラスMyQIは、IRule インターフェイス及びIUnknownインターフェイスを実施するルールオブジェクトである。理解を容易にするために、クラスMyQIは、非集合可能なオブジェクトとして示されている。IRule インターフェイスは、このルールオブジェクトを含む囲んでいるマルチタイプオブジェクト（ＭＴＯ）のポインタを維持するためのメソッドInitを与える。このＭＴＯポインタは、IMultitypeインターフェイスのメソッドEnumをアクセスするように後で使用され、集合されたインターフェイス及びオブジェクトをアクセスすることができる。メソッドInitは、ルールオブジェクトのリストにルールオブジェクトが追加されるときにAddRule によって呼び出される。IUnknownインターフェイスは、ルールオブジェクトのリストから組み合わせルールオブジェクトをいかに選択するかを知るQueryInterfaceの実施を与える。図示されたように、MyQI::QueryInterfaceは、MTO::QueryInterface により与えられるものと同一の機能を与える。しかしながら、その実施は、MyQI::QueryInterfaceがメソッドEnumを用いて組み合わせルールを見つけるのであって、リスト自体をサーチするのではない点で異なる。MTO::QueryInterface は同様に実施できることが当業者に明らかであろう。
【０１２８】
MyQIルールオブジェクトを用いる例がメソッドMTO::MTOにおいて示される。マルチタイプオブジェクトが具体化されるときには、構成子MTO::MTOが呼び出される。この構成子は、MyQIクラス定義を用いてIUnknownインターフェイスに対する新たなルールオブジェクトを形成し、次いで、このルールオブジェクトをメソッドAddRule を用いてルールオブジェクトのリストに追加する。選択ルールを実施するルールオブジェクトの追加はいつでも容易に実行できることが当業者に明らかであろう。
0004322967.tif 000042
0004322967.tif 000043
0004322967.tif 000044
【０１２９】
コード表１４は、マルチタイプオブジェクト及びルールオブジェクトを用いて１組の集合されたオブジェクト又はインターフェイスに対するオーバーライド動作を与えるＣ＋＋擬似コードを示している。典型的に、異なるタイプの１組のオブジェクトが集合されたときには、各オブジェクトは、オブジェクトをいかにプリントするかを知るそれ自身のプリントメソッドを与える。コード表１４は、IPrintインターフェイスの組み合わせルールを与えるルールオブジェクトの好ましいクラス定義のＣ＋＋擬似コードを示す。与えられたIPrintインターフェイスはメソッドPrint を含み、これは、囲んでいるマルチタイプオブジェクトにおける各囲まれたオブジェクト又はインターフェイスのプリントメソッドを呼び出すものである。
【０１３０】
クラスMyPrintRule は、全てのルールオブジェクトと同様に、少なくとも２つのインターフェイス、この場合はIRule 及びIPrintに対する実行を与える。クラスMyPrintRule によって与えられるIRule インターフェイスは、コード表１３を参照して既に述べたクラスMyQIと機能的に同一である。IPrintインターフェイスは、マルチタイプオブジェクトにおける集合されたオブジェクトの３つのリストを通して列挙する組み合わせルールを単に与えるもので、他のIPrintインターフェイスをサーチして、見つかった際にそれらのPrint ルールを呼び出す。コード表１３について述べたように、このルールオブジェクトがマルチタイプオブジェクトにおけるルールオブジェクトのリストに追加された後に、マルチタイプオブジェクトの制御IUnknownのメソッドQueryInterfaceは、クライエントアプリケーションがその集合されたオブジェクトにおけるIID  IPrintを要求するQueryInterfaceを呼び出すときに、この組み合わせルールIPrintインターフェイスのポインタを返送するのが好ましい。その結果、クライエントアプリケーションがメソッドPrint を呼び出すときには、このルールオブジェクトによって実行されるメソッドPrint が呼び出されて、その集合されたオブジェクトがその成分を正しくプリントするように確保する。
0004322967.tif 000045
【０１３１】
コード表１５は、コード表１４で定められたルールオブジェクトをインストールするコールのＣ＋＋擬似コードシーケンスを示す。先ず、クラスmyPrintRule ルールオブジェクトの新たなインスタンスが形成される。第２に、この新たなルールオブジェクトのIRule インターフェイスが後で使用するように検索される。第３に、マルチタイプオブジェクト(p MTO)のポインタをどこからか得た後に、マルチタイプオブジェクトのIMultitypeインターフェイスが検索される。最終的に、この検索されたIMultitypeインターフェイスのメソッドAddRule が呼び出され、これに、新たなルールオブジェクト(IID IPrint) に対するインターフェイス識別子及び新たなルールオブジェクトのIRule インターフェイスを通す。
【０１３２】
好ましい実施例では、集合されたオブジェクトは、プリントについて説明した同じメカニズムを用いて永続的に記憶される。特に、マルチタイプオブジェクトは、IPersistFileインターフェイス又は他のインターフェイスに対する組み合わせオブジェクトを与え、これは、オブジェクトをセーブしそして検索する役割を果たす。（IPersistFileインターフェイスは、オブジェクトをセーブしそしてロードするメソッドである。）このように、マルチタイプオブジェクトは、囲まれたオブジェクト及びインターフェイスのセーブ機能にオーバーライドして、集合された全てのオブジェクトがセーブされるように確保する。組み合わせルールはマルチタイプオブジェクトが最初に必要とするデータ構造をセーブし、そして囲まれたIPersistFileインターフェイス又はオブジェクトの各々においてメソッドSaveを呼び出す。従って、集合オブジェクトをセーブすることに関与するために、クライエントプログラムは、囲まれるべきオブジェクトのIPersistFileインターフェイスを追加するか、又は全オブジェクトを囲い込む。個別のファイルに個別の記憶が必要とされるのではない。マルチタイプオブジェクトは、オブジェクトデータを単一のファイル内に記憶したのと同様の仕方でそれ自身のデータを記憶することができる。
【０１３３】
集合されたインターフェイス又はオブジェクトとルールの１つのリストのみを実施する（３つのリストとルールオブジェクトのリストではなくて）別の実施例では、マルチタイプオブジェクトはそれ自身の記憶を必要としない。集合されたオブジェクトにより使用されるもの以外の記憶は必要でない。というのは、マルチタイプオブジェクトは、ハイアラーキ式の永続記憶構造において集合されたオブジェクトの順序及びインデックス情報を検査することにより単一リストを再形成できるからである。しかしながら、多数のインターフェイスリストを実行するマルチタイプオブジェクトは、どのインターフェイスインスタンスがどのリストによって指されるかを区別するために情報を記憶することを一般に必要とする。
【０１３４】
本発明のここに示す実施例は、制御IUnknown::QueryInterfaceメソッドが囲まれたオブジェクトのQueryInterfaceメソッドを呼び出すときに、このような呼び出しが同期しておこなわれると仮定する。即ち、囲まれたオブジェクトQueryInterfaceメソッドは、制御IUnknown::QueryInterfaceメソッドが次の囲まれたオブジェクトQueryInterfaceメソッドを呼び出す前に復帰する。別の実施例では、制御IUnknown::QueryInterfaceメソッドは、囲まれたオブジェクトQueryInterfaceメソッドを、それらの復帰を待機せずに非同期で呼び出す。むしろ、標準的なプロセス間通信メカニズムを用いて、囲まれたオブジェクトメソッドが完了したときに制御ルーチンを知らせる。このような実施例は、ネットワーク又はマルチプロセッサ環境において有用である。
【０１３５】
動的な集合に対する本発明の典型的なアプリケーションは、動的な集合の知識で開発されたプログラムを用いてユーザがオブジェクトのインスタンスを更に強力なオブジェクトへと組み合わせることである。例えば、背景技術で説明したスプレッドシートインターフェイスの例を用いて、ソフトウェアの販売者がスプレッドシート製品を出荷し、そこからユーザがスプレッドシートの基本的な操作に対しIBasicインターフェイスのみをサポートする集合可能なスプレッドシートオブジェクトを形成できると仮定する。（即ち、この製品を用いて、ユーザは、スプレッドシートオブジェクトであるIBasicインターフェイスのインスタンスを形成することができる。）更に、別のソフトウェア販売者がデータベース製品を出荷し、そこからユーザが集合可能なデータベース問合せオブジェクトを形成できると仮定する。これらの集合可能なデータベース問合せオブジェクトは、IDatabaseQueryインターフェイスをサポートし、これは、例えば、問合せを実行するメソッドDoQuery と、ユーザが問合せを指定できるようにするメソッドDefineQuery とを備えている。入力データとして働くことのできる他のオブジェクトに取り付けられたときに、これらのデータベース問合せオブジェクトは、その取り付けられた入力データに問い合わせをするように呼び出すことができる。又、コンピュータシステム上にプログラムが常駐し、例えば、オブジェクトをマネージしそしてマルチタイプオブジェクトをいかに形成し他のオブジェクト及びインターフェイスを一緒に集合するかを知るファイルマネージャが常駐すると仮定する。このタスクを行うために、ファイルマネージャは、IMultitypeインターフェイスの実行を与えるマルチタイプオブジェクトをいかに形成するかを知る。
【０１３６】
図１５は、取り付けられたデータベース問合せオブジェクトを形成するように一緒に集合することのできるスプレッドシートオブジェクト及びデータベース問合せオブジェクトを示す図である。指定されたデータベースにおいて指定された問合せを実行することのできる更に強力なオブジェクト（取り付けられたデータベース問合せオブジェクト１２０５）を形成するために、ユーザは、先ず、スプレッドシート製品を用いて、ユーザが入力データとして使用しようとするスプレッドシートオブジェクト１２０１のインスタンスを形成する。次いで、ユーザは、データベース製品を用いて、データベース問合せオブジェクト１２０２のインスタンスを形成する。次いで、ユーザは、定義ボタン１２０４を押すことによりIDatabaseQueryインターフェイスのメソッドDefineQuery を呼び出し、そしてデータベース言語、例えば、ＳＱＬ言語を用いてデータベース問合せに対するテキストを入力する。次いで、ユーザは、ファイルマネージャ１２０８を呼び出す。このファイルマネージャを用いて、ユーザは、スプレッドシートオブジェクト１２０１及びデータベース問合せオブジェクト１２０２を選択し、ファイルマネージャ１２０８がそれらを集合することを要求する。ユーザは、例えば、スプレッドシートオブジェクト１２０１のディスプレイ表示をデータベース問合せオブジェクト１２０２のディスプレイ表示のデータ入力ポート１２０３にドラグ及びドロップすることにより、この要求を指示することができる。ユーザの要求に応答して、ファイルマネージャ１２０８は、囲んでいるマルチタイプオブジェクトを具体化しそしてスプレッドシートオブジェクト１２０１及びデータベース問合せオブジェクト１２０２の両方に対してメソッドIMultitype::AddObject を呼び出すことにより、新たに取り付けられたデータベース問合せオブジェクト１２０５を具体化する。又、ファイルマネージャ１２０８は、スプレッドシートオブジェクト１２０１及びデータベース問合せオブジェクト１２０２の両方に、この新たに具体化されたマルチタイプオブジェクトの制御IUnknownインターフェイスのポインタを通す。次いで、ユーザは、"Go"ボタン１２０６を選択することによりその取り付けられたデータベース問合せオブジェクトを呼び出して、その取り付けられたスプレッドシートデータにおいて指定の問合せを実行することができる。
【０１３７】
オブジェクトがいったん集合されると、囲んでいるオブジェクトのルールがそれに適用されることが当業者に明らかであろう。従って、スプレッドシートオブジェクト１２０１及びデータベース問合せオブジェクトの動作は、いったん囲まれると、変更し得る。
【０１３８】
図１６は、集合された取り付けられたデータベース問合せオブジェクトを示すブロック図である。集合されたオブジェクト１３０４は、図１５を参照して述べた取り付けられたデータベース問合せオブジェクトに対応する。集合されたオブジェクト１３０４は、マルチタイプオブジェクト１３０１と、スプレッドシートオブジェクト１３０２と、データベース問合せオブジェクト１３０３とを備えている。マルチタイプオブジェクト１３０１は、上記のように、ユーザ要求に応答して、スプレッドシートオブジェクト１３０２及びデータベース問合せオブジェクト１３０３を集合するように形成される。集合のプロセス中に、マルチタイプオブジェクトは、集合されたオブジェクトに対するポインタ１３０５及び１３０６を形成し、そして集合されるべきオブジェクトに、制御IUnknownインターフェイスに対するポインタを通す。その後に、ユーザが"Go"ボタン（図１５の１２０６）を押したときに、マルチタイプオブジェクト１３０７の制御IUnknownインターフェイスが呼び出され、上記実施例を用いてデータベース問合せオブジェクト１３０３のIDatabaseQueryインターフェイスのメソッドDoQuery を呼び出す。メソッドDoQuery は、次いで、メソッドQueryInterfaceを用いてスプレッドシートオブジェクト１３０２の（既知の）所望のインターフェイス識別子をサーチすることによりスプレッドシートオブジェクト１３０２の（既知の）所望のメソッドに問合せしそして呼び出す。（再呼び出しのために、メソッドQueryInterfaceの呼び出しは、制御IUnknown１３０７のメソッドQueryInterfaceにマルチタイプオブジェクト１３０１を送り、これは、もし存在すれば所望のインターフェイスを位置決めする。）従って、データベース問合せオブジェクト１３０３は、メソッド及びインターフェイス識別子の名前（及びパラメータ）が分かる限り、スプレッドシートオブジェクト１３０２のインターフェイスのコンパイル時間定義をアクセスする必要なく、スプレッドシートオブジェクト１３０２のメソッドを呼び出すことができる。
【０１３９】
以上、好ましい実施例について本発明を説明したが、本発明は、これらの実施例に限定されるものではない。当業者であれば、本発明の範囲内で変更がなされ得ることが明らかであろう本発明の範囲は、特許請求の範囲のみによって限定されるものとする。
【図面の簡単な説明】
【図１】オブジェクトを表現するのに使用される典型的なデータ構造を示すブロック図である。
【図２】ネストクラスを用いるスプレッドシートオブジェクトのサンプルデータ構造を示すブロック図である。
【図３】集合オブジェクトを示すブロック図である。
【図４】クラスＳ１のオブジェクトのインスタンスのデータ構造レイアウトを示すブロック図である。
【図５】クラスＳ３のオブジェクトのデータ構造レイアウトを示すブロック図である。
【図６】囲んでいるオブジェクトと囲まれたオブジェクトとの間の協働を示すブロック図である。
【図７】囲んでいるオブジェクトと囲まれたオブジェクトとの間の協働を示すブロック図である。
【図８】２つのオブジェクトをマルチタイプオブジェクトに加えるシーケンスを示すブロック図である。
【図９】２つのオブジェクトをマルチタイプオブジェクトに加えるシーケンスを示すブロック図である。
【図１０】２つのオブジェクトをマルチタイプオブジェクトに加えるシーケンスを示すブロック図である。
【図１１】クラスＳ１のオブジェクトのインスタンスのデータ構造レイアウトを示すブロック図である。
【図１２】マルチタイプオブジェクトによって実施されるIMultitypeインターフェイスのメソッドAddInterfaceを示すフローチャートである。
【図１３】マルチタイプオブジェクトに対する制御IUnknownインターフェイスのメソッドQueryInterfaceを示すフローチャートである。
【図１４】メソッドAddObject を用いてIBasic、IPrint及びIDatabase インターフェイスが動的に集合された後の図１０に対応するマルチタイプオブジェクトのデータ構造レイアウトを示すブロック図である。
【図１５】取り付けられたデータベース問合せオブジェクトを形成するように一緒に集合することのできるスプレッドシートオブジェクト及びデータベース問合せオブジェクトを示す図である。
【図１６】集合され取り付けられたデータベース問合せオブジェクトを示すブロック図である。
【符号の説明】
３０１  囲んでいるオブジェクト
３０２、３０３  囲まれたオブジェクト
３０４  実現部
４０１  インスタンス構造体
４０２、４０３  仮想関数表
４０４−４１６  関数
５０１  インスタンスデータ
５０２、５０３、５０４  仮想関数表
５０５−５１７  メソッド
６０１  クラスＳ１オブジェクト
６０３、６０４、６０５、６０６  メソッド
【図１】
0004322967.tif 000046
【図２】
0004322967.tif 000047
【図３】
0004322967.tif 000048
【図４】
0004322967.tif 000049
【図５】
0004322967.tif 000050
【図６】
0004322967.tif 000051
【図７】
0004322967.tif 000052
【図８】
0004322967.tif 000053
【図９】
0004322967.tif 000054
【図１０】
0004322967.tif 000055
【図１１】
0004322967.tif 000056
【図１２】
0004322967.tif 000057
【図１３】
0004322967.tif 000058
【図１４】
0004322967.tif 000059
【図１５】
0004322967.tif 000060
【図１６】
0004322967.tif 000061