C, C++ 문법

논리상 생성자에서 처리해도 되는 것을 Init 함수를 따로 빼서 사용하는 이유

디버그정 2008. 8. 27. 22:54

생성자는 리턴값을 따로 두지 않는다. 에러를 조사하고자 하는 경우는 리턴값으로 확인할 수 없다.

그래서 초기화 함수를 따로 빼서 코딩해야하는 경우가 있다.
컴포넌트 관련 코딩에서 많이 발견된다.
물론 객체 생성후 항상 Init함수를 호출해준다.

다음은 그 예이다.

// 생성자
COEnumConnections::COEnumConnections(
  IUnknown* pHostObj)
{
  // Zero the COM object's reference count.
  m_cRefs = 0;

  // Assign the Host Object pointer.
  m_pHostObj = pHostObj;

  // Initialize the Connection Point enumerator variables.
  m_iEnumIndex = 0;
  m_cConnections = 0;
  m_paConnections = NULL;

  return;
}


// 이니셜라이즈
HRESULT COEnumConnections::Init(
          ULONG cConnections,
          CONNECTDATA* paConnections,
          ULONG iEnumIndex)
{
  HRESULT hr = NOERROR;
  UINT i;

  // Remember the number of live Connections.
  m_cConnections = cConnections;

  // Remember the initial enumerator index.
  m_iEnumIndex = iEnumIndex;

  // Create a copy of the array of connections and keep it inside
  // this enumerator COM object.
  m_paConnections = new CONNECTDATA [(UINT) cConnections];

  // Fill the array copy with the connection data from the connections
  // array passed. AddRef for each new sink Interface pointer copy made.
  if (NULL != m_paConnections)
  {
    for (i=0; i<cConnections; i++)
    {
      m_paConnections[i] = paConnections[i];
      m_paConnections[i].pUnk->AddRef();
    }
  }
  else
    hr = E_OUTOFMEMORY;

  return (hr);
}

// 에러값 검사의 예
STDMETHODIMP COEnumConnections::Clone(
               IEnumConnections** ppIEnum)
{
  HRESULT hr;
  COEnumConnections* pCOEnum;

  // NULL the output variable first.
  *ppIEnum = NULL;

  // Create the Clone Enumerator COM object.
  pCOEnum = new COEnumConnections(m_pHostObj);
  if (NULL != pCOEnum)
  {
    // Initialize it with same values as in this existing enumerator.
    hr = pCOEnum->Init(m_cConnections, m_paConnections, m_iEnumIndex);
    if (SUCCEEDED(hr)) // <---- 이니셜라이즈의 에러값 검사
    {
      // QueryInterface to return the requested interface pointer.
      // An AddRef will be conveniently done by the QI.
      if (SUCCEEDED(hr))
        hr = pCOEnum->QueryInterface(
                        IID_IEnumConnections,
                        (PPVOID)ppIEnum);
    }
  }
  else
    hr = E_OUTOFMEMORY;

  return hr;
}