CComObject、CComAggObject、および CComPolyObject の実装

更新 : 2007 年 11 月

テンプレート クラス CComObjectCComAggObject、および CComPolyObject は、常に継承チェインの最派生クラスになります。IUnknown のすべてのメソッド (QueryInterfaceAddRef、および Release) を処理するのがこれらのテンプレート クラスの役割です。また、CComAggObjectCComPolyObject は、集約オブジェクトに使用された場合、内部オブジェクトの IUnknown に必要な特別な参照カウントと QueryInterface を提供します。

CComObjectCComAggObject、または CComPolyObject のうち、どのテンプレート クラスが使用されるかは、以下のどのマクロを宣言するか (あるいはどれも宣言しない) によって異なります。

マクロ

効果

DECLARE_NOT_AGGREGATABLE

常に CComObject を使用します。

DECLARE_AGGREGATABLE

集約オブジェクトの場合は CComAggObject を使用します。非集約オブジェクトの場合は CComObject を使用します。CComCoClass にはこのマクロが含まれるため、クラスでどの DECLARE_*_AGGREGATABLE マクロも宣言されない場合は、このクラスが既定値になります。

DECLARE_ONLY_AGGREGATABLE

常に CComAggObject を使用します。非集約オブジェクトの場合はエラーを返します。

DECLARE_POLY_AGGREGATABLE

ATL では、IClassFactory::CreateInstance が呼び出されると、CComPolyObject<CYourClass> のインスタンスが作成されます。インスタンスの作成時には、外側の IUnknown の値がチェックされます。値が NULL の場合、IUnknown は非集約オブジェクト用に実装されます。外側の IUnknownNULL でない場合、IUnknown は集約オブジェクト用に実装されます。

CComAggObjectCComObject を使用する利点は、IUnknown の実装が、作成されるオブジェクトの種類に合わせて最適化されることです。たとえば、非集約オブジェクトには、参照カウントだけが必要です。一方、集約オブジェクトには、内部オブジェクトの IUnknown の参照カウントと、外側の IUnknown へのポインタの両方が必要です。

CComPolyObject を使用する利点は、集約クラスと非集約クラスを処理するときに、モジュールに CComAggObjectCComObject の両方を持つ必要がないことです。CComPolyObject オブジェクトが 1 つあれば両方を扱うことができます。つまり、モジュール中には vtable のコピーと関数のコピーがそれぞれ 1 つだけ存在することになります。vtable のサイズが大きい場合は、これによってモジュール サイズを大幅に縮小できます。ただし、vtable のサイズが小さい場合は、CComPolyObject を使うとモジュール サイズが逆に大きくなってしまう可能性があります。これは、CComAggObjectCComObject とは異なり、CComPolyObject は集約オブジェクトや非集約オブジェクト用に最適化されていないためです。

参照

参照

ATL COM オブジェクトの基本事項

その他の技術情報

集約とクラス ファクトリに関するマクロ