Re: exceptions in constructor
This is a multi-part message in MIME format.
------=_NextPart_000_0059_01C93222.281D1040
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<vaclavpich@atlas.cz> wrote in message =
news:a86624e5-ceef-4c5c-a369-21f67fb935e4@d31g2000hsg.googlegroups.com...=
CObject::CObject()
{
// 1) if ( FAILED( LoadLibrary(...) )) throw exception1;
// 2) if ( FAILED(CoInitialize( 0 )) throw exception2;
// 3) if ( FAILED( CoCreateInstance(....))) throw exception3;
}
CObject::~CObject()
{
// 1) release COM interface
// 2) CoUninitialize();
// 2) FreeLibrary
}
you should put the separate objects (HANDLE returned by LoadLibrary, =
CoInitialize()/CoUninitialize() and CoCreateInstance()) into separate =
classes and combine these classes into base-class or member-class =
relationships.
Doing it this way you don't have to clean up yourself anymore but rely =
on the code generation features of the compiler. And you can reuse these =
classes next time you're calling these functions.
And the caller of you'r code will get rich error information.
class CPLoadLibrary
{ private:
HINSTANCE h;
public:
inline CPLoadLibrary(const _TCHAR *pName)
{ if (!(h = LoadLibrary(pName)))
throwSystemException(
GetLastError(),
CString(_T("LoadLibrary(\"")) + CString(pName) + =
CString(_T("\")")));
}
inline ~CPLoadLibrary(void)
{ FreeLibrary(h);
}
inline void *getProcAddress(const char *pName)
{ void *p;
if (!(p = ::GetProcAddress(h, pName)))
throwSystemException(
GetLastError(),
_T("GetProcAddress()"));
return p;
}
inline operator HINSTANCE (void)
{ return h;
}
inline HINSTANCE getHINSTANCE(void)
{ return h;
}
};
template<class T, const IID *_piREFIID>
class CPCoCreateInstance
{ private:
T *m_p;
public:
inline CPCoCreateInstance(
REFCLSID _iCLSID,
IUnknown *_pUnkOuter,
DWORD _iClsContext)
{ HRESULT iRet;
m_p = 0;
if (FAILED(iRet = CoCreateInstance(_iCLSID, _pUnkOuter, =
_iClsContext, *_piREFIID, (void**)&m_p)))
throwSystemException(iRet, _T("CoCreateInstance()"));
if (!m_p)
throwSystemException(E_FAIL, _T("CoCreateInstance()"));
}
inline ~CPCoCreateInstance(void)
{ if (m_p)
m_p->Release();
}
inline operator T *(void)
{ return m_p;
}
inline T *getPtr(void)
{ return m_p;
}
inline T *detach(void)
{ T *pRet = m_p;
m_p = 0;
return pRet;
}
};
class CPCoInitializeEx
{ private:
public:
inline CPCoInitializeEx(void *_pReserved, DWORD _iFlags)
{ HRESULT iRet;
if (FAILED(iRet = CoInitializeEx(_pReserved, _iFlags)))
throwSystemException(iRet, _T("CoInitializeEx() failed!"));
}
inline ~CPCoInitializeEx(void)
{ CoUninitialize();
}
};
------=_NextPart_000_0059_01C93222.281D1040
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; =
charset=iso-8859-1">
<META content="MSHTML 6.00.6001.18148" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2><</FONT><A
href="mailto:vaclavpich@atlas.cz"><FONT face=Arial
size=2>vaclavpich@atlas.cz</FONT></A><FONT face=Arial size=2>> =
wrote in
message </FONT><A
href="news:a86624e5-ceef-4c5c-a369-21f67fb935e4@d31g2000hsg.googlegroup=
s.com"><FONT
face=Arial
size=2>news:a86624e5-ceef-4c5c-a369-21f67fb935e4@d31g2000hsg.googlegrou=
ps.com</FONT></A><FONT
face=Arial size=2>...</FONT></DIV>
<DIV><FONT face=Arial size=2>> CObject::CObject()<BR>> =
{<BR>> //
1) if ( FAILED( LoadLibrary(...) )) throw exception1;<BR>> =
<BR>> //
2) if ( FAILED(CoInitialize( 0 )) throw exception2;<BR>>
<BR>> // 3) if ( FAILED( CoCreateInstance(....))) throw
exception3;<BR>> }<BR>> <BR>> CObject::~CObject()<BR>>
{<BR>> // 1) release COM interface<BR>> <BR>> // 2)
CoUninitialize();<BR>> <BR>> // 2) FreeLibrary<BR>>
}<BR></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>you should put the separate objects =
(HANDLE
returned by LoadLibrary, CoInitialize()/CoUninitialize() and =
CoCreateInstance())
into separate classes and combine these classes into base-class or =
member-class
relationships.</FONT></DIV>
<DIV><FONT face=Arial size=2>Doing it this way you don't have to =
clean up
yourself anymore but rely on the code generation features of the =
compiler. And
you can reuse these classes next time you're calling these
functions.</FONT></DIV>
<DIV><FONT face=Arial size=2>And the caller of you'r code will get =
rich error
information.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>class
CPLoadLibrary<BR>{ private:<BR> HINSTANCE
h;<BR> public:<BR> inline CPLoadLibrary(const _TCHAR
*pName)<BR> { if (!(h =
LoadLibrary(pName)))<BR> throwSystemException(<BR> =
GetLastError(),<BR>
CString(_T("LoadLibrary(\"")) + CString(pName) +
CString(_T("\")")));<BR> }<BR> inline
~CPLoadLibrary(void)<BR> { FreeLibrary(h);<BR> }<BR> =
inline
void *getProcAddress(const char *pName)<BR> { void =
*p;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> if (!(p = =
::GetProcAddress(h,
pName)))<BR> throwSystemException(<BR> =
GetLastError(),<BR>
_T("GetProcAddress()"));<BR> return =
p;<BR> }<BR> inline
operator HINSTANCE (void)<BR> { return =
h;<BR> }<BR> inline
HINSTANCE getHINSTANCE(void)<BR> { return
h;<BR> }<BR>};</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>template<class T, const IID =
*_piREFIID>
<BR>class CPCoCreateInstance<BR>{ private:<BR> T
*m_p;<BR> public:<BR> inline
CPCoCreateInstance(<BR> REFCLSID
_iCLSID,<BR> IUnknown
*_pUnkOuter,<BR> DWORD
_iClsContext)<BR> { HRESULT iRet;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> m_p = =
0;<BR> if (FAILED(iRet
= CoCreateInstance(_iCLSID, _pUnkOuter, _iClsContext, *_piREFIID,
(void**)&m_p)))<BR> throwSystemException(iRet,
_T("CoCreateInstance()"));<BR> if
(!m_p)<BR> throwSystemException(E_FAIL,
_T("CoCreateInstance()"));<BR> }<BR> inline
~CPCoCreateInstance(void)<BR> { if
(m_p)<BR> m_p->Release();<BR> }<BR> inline =
operator T *(void)<BR> { return =
m_p;<BR> }<BR> inline T
*getPtr(void)<BR> { return m_p;<BR> }<BR> inline T
*detach(void)<BR> { T *pRet = m_p;<BR> m_p =
0;<BR> return pRet;<BR> }<BR>};<BR></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>class
CPCoInitializeEx<BR>{ private:<BR> public:<BR> inline
CPCoInitializeEx(void *_pReserved, DWORD =
_iFlags)<BR> { HRESULT
iRet;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> if (FAILED(iRet =
CoInitializeEx(_pReserved,
_iFlags)))<BR> throwSystemException(iRet, =
_T("CoInitializeEx()
failed!"));<BR> }<BR> inline
~CPCoInitializeEx(void)<BR> { CoUninitialize();<BR> }<BR>}=
;</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV></BODY></HTML>
------=_NextPart_000_0059_01C93222.281D1040--