作成したオブジェクトに必要な初期化を行うには、派生クラス内でこのメソッドをオーバーライドします。
HRESULT FinalConstruct( );
戻り値
正常に終了した場合は、S_OK を返します。それ以外の場合は、標準の HRESULT 値のいずれかを返します。
解説
既定では CComObjectRootEx::FinalConstruct は単に S_OK を返します。
作成したクラスのコンストラクターではなく、FinalConstruct で初期化を行うと、次のような利点があります。
コンストラクターからのステータス コードを返すことはできませんが、FinalConstruct の戻り値という形で HRESULT を返すことができます。 ATL (Active Template Library) で提供されている標準的なクラス ファクトリを使用してクラスのオブジェクトを作成している場合、この戻り値は COM クライアントにも渡されます。そのため、エラーの詳細情報をオブジェクトに提供できます。
クラスのコンストラクターから仮想関数の機構を使用して、仮想関数を呼び出すことはできません。 クラスのコンストラクターから仮想関数を呼び出した場合、継承階層の中でその時点で定義されている関数への呼び出しとして、静的に解決されます。 純粋仮想関数を呼び出すと、リンカー エラーが発生します。
作成したクラスは継承階層の最派生クラスではなく、その機能の一部を提供するために、ATL が提供する派生クラスに依存しています。 オブジェクトの初期化時には、このクラスが提供する機能が必要とされる場合がよくありますが (特に、クラスのオブジェクトがほかのオブジェクトをアグリゲートする必要がある場合など)、このクラスのコンストラクターでは、それらの機能にアクセスできません。 クラスの構築コード (コンストラクター) は、最派生クラスが完全に構築される前に実行されるためです。
一方、FinalConstruct は最派生クラスが完全に構築された直後に呼び出されます。そのため、このメソッドを使用すると、仮想関数を呼び出したり、ATL で提供されている参照カウントの実装を使用したりできます。
使用例
通常は、このメソッドを CComObjectRootEx から派生したクラスでオーバーライドして、アグリゲートされるオブジェクトを作成します。 次に例を示します
class ATL_NO_VTABLE CMyAggObject :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyAggObject, &CLSID_MyAggObject>,
public IDispatchImpl<IMyAggObject, &IID_IMyAggObject, &LIBID_NVC_ATL_COMLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
DECLARE_GET_CONTROLLING_UNKNOWN()
HRESULT FinalConstruct()
{
return CoCreateInstance(CLSID_MyCustomClass, GetControllingUnknown(),
CLSCTX_ALL, IID_IUnknown, (void**)&m_pMyCustomClass);
}
IMyCustomClass* m_pMyCustomClass;
// Remainder of class declaration omitted.
構築に失敗した場合は、エラーを返すことができます。 また、オブジェクトの作成時に、アグリゲートされる内部オブジェクトが参照カウントをインクリメントした後でデクリメントして 0 に戻す場合は、DECLARE_PROTECT_FINAL_CONSTRUCT マクロを使用すると、外部オブジェクトが削除されないように保護できます。
次に、集約を作成する典型的な方法を示します。
クラス オブジェクトに IUnknown ポインターを追加し、コンストラクターで IUnknown ポインターを NULL に初期化します。
FinalConstruct をオーバーライドして、集約を作成するようにします。
ここで定義した IUnknown ポインターを COM_INTERFACE_ENTRY_AGGREGATE マクロのパラメーターとして使用します。
FinalRelease をオーバーライドして、IUnknown ポインターを解放するようにします。
必要条件
**ヘッダー:**atlcom.h
参照
参照
CComObjectRootEx::FinalRelease
DECLARE_GET_CONTROLLING_UNKNOWN