Is it OK to have the following code in my constructor to load an XML document into a member variable - throwing to caller if there are any problems:
MSXML2::IXMLDOMDocumentPtr m_docPtr; //member
Configuration()
{
try
{
HRESULT hr = m_docPtr.CreateInstance(__uuidof(MSXML2::DOMDocument40));
if ( SUCCEEDED(hr))
{
m_docPtr->loadXML(CreateXML());
}
else
{
throw MyException("Could not create instance of Dom");
}
}
catch(...)
{
LogError("Exception when loading xml");
throw;
}
}
Based on Scott Myers RAII implementations in More Effective C++ he cleanups if he alocates any resources i.e. pointers:
BookEntry::BookEntry(const string& name,
const string& address,
const string& imageFileName,
const string& audioClipFileName)
: theName(name), theAddress(address),
theImage(0), theAudioClip(0)
{
try { // this try block is new
if (imageFileName != "") {
theImage = new Image(imageFileName);
}
if (audioClipFileName != "") {
theAudioClip = new AudioClip(audioClipFileName);
}
}
catch (...) { // catch any exception
delete theImage; // perform necessary
delete theAudioClip; // cleanup actions
throw; // propagate the exception
}
}
I believe I am alright in just allowing exceptions to be thrown from CTOR as I am using a smart pointer(IXMLDOMDocumentPtr).
Let me know what you think....
C++ guarantees that in case of an exception all fully constructed objects will be destroyed.
Since m_docPtr
is a member of class Configuration
it will have been fully constructed before the class Configuration
constructor body begins, so if you throw an exception from class Configuration
body as you intended in your first snippet m_docPtr
will be destroyed.