3. Implementation/COM & ActiveX

FinalConstruct & FinalRelease

SSKK 2008. 10. 26. 09:23

CComObjectRootEx::FinalConstruct

 

객체의 초기화를 수행한다.

 

클래스 생성자 대신 FinalConstruct에서 초기화를 수행할 시의 장점은 다음과 같다.

 

l  생성자에서는 상태 코드를 반환할 수 없지만, FinalConstruct 에서는 HRESULT 값을 반환값으로 사용할 수 있다. ATL에서 제공하는 표준 클래스 팩토리가 클래스의 객체를 생성할 때 이 반환값은 상세한 에러 정보를 제공할 수 있도록 COM 클라이언트에게 전파된다.

l  가상 함수 매커니즘에서는 클래스의 생성자에서 순수 가상 함수를 호출할 수 없다. 클래스의 생성자에서 가상 함수를 호출하는 것은 상속 계층에서 생성 되는 시점에 정의되어 있는 함수만을 호출한다. ( 순수 가상 함수에 대한 호출은 링크 에러를 초래한다.

 

당신의 클래스는 상속 계층에서 최하위 파생 클래스(the most derived class)가 아닐 때 어떤 기능을 지원하기 위해 ATL에서 제공된 파생 클래스라고 기대한다. 초기화가 그 클래스(ATL)에서 제공하는 기능을 사용할 좋은 기회이지만 ( 이것은 당신의 클래스 객체가 다른 객체에 집합(aggregate)될 때는 반드시 그러하다 ) , 당신의 클래스 생성자는 최하위 파생 클래스의 기능에 접근할 수 있는 방법이 없다. 당신 클래스의 생성 코드는 최하위 파생 클래스가 완전히 생성되기 전에 실행된다.

 

그러나, FinalConstruct 는 최하위 파생 클래스가 완전히 생성된 후에 즉시 호출되기 때문에 가상함수를 호출할 수 있고 ATL에서 제공하는 참조-카운트 구현을 사용할 수 있다.

 

예제

일반적으로 모든 집합된 객체 (aggregated object)를 생성하기 위해서는 CComObjectRootEx를 상속한 클래스 내에서 이 메소드를 재정의한다.

class CMyAggObject : public CComObjectRootEx< ... >

{

   DECLARE_GET_CONTROLLING_UNKNOWN( )

   HRESULT FinalConstruct( )

   {

      return CoCreateInstance(CLSID_SomeServer,

               GetControllingUnknown(), CLSCTX_ALL,

               IID_ISomeServer, &m_pSomeServer);

   }

   ...

};

 

만일 생성이 실패한다면, 에러를 반환할 수 있다. 또한 생성되는 동안 만일 내부 집합 객체(internal aggregated object)가 참조 카운트를 증가시키고 그러고 나서 참조 카운트를 0으로 감소시킬 때 외부 객체 (outer object)가 삭제되는 것을 보호하기 위해 DECLARE_PROTECT_FINAL_CONSTRUCT 매크로를 사용할 수 있다.

 

아래는 집합체를 생성하는 일반적인 방법이다.

l  클래스 객체에 IUnknown 포인터를 추가하고 생성자에서 NULL 로 초기화 한다.

l  집합체(aggregate)를 생성하기 위해 FinalConstruct를 재정의 한다.

l  당신이 정의한 IUnknown 포인터를 COM_INTERFACE_ENTRY_AGGREGATE 매크로의 파라미터로 사용한다.

l  IUnknown 포인터를 해제 하기 위해 FinalRelease를 재정한다.

 

CComObjectRootEx::FinalRelease

 

객체의 클린업을 수행하기 위해 파생 클래스에서 이 메소드를 재정의 할 수 있다.

 

기본적으로, CComObjectRootEx::FinalRelease 는 아무것도 하지 않는다.

 

FinalRelease에서 클린업을 수행하는 것은 클래스의 소멸자에 클린업 코드를 추가하는 것보다 선호된다 왜냐하면 그 객체는 FinalRelease 가 호출되는 시점에도 여전히 완전히 생성되어 있기 때문이다. 이것은 이것은 최하위 파생클래스에서 제공하는 메소드에 대한 안전한 접근을 가능하게 한다. 이것은 삭제되기 전에 모든 집합 객체(any aggregated objects)를 해제하는 경우 특히 중요하다.

 

참고 : MSDN 2005