Search code examples
c++visual-c++smart-pointersmsxml

c++, msxml and smart pointers


I need parse some XML and wrote some helpers. I am not expert in C++, actually I wrote with c more then seven years ago. So, I would to make sure, is the approach, what i use correct or not :)

1) I implemented some simple helpers, to take care about exceptions. For example:

CComPtr<IXMLDOMElement> create_element(CComPtr<IXMLDOMDocument> xml_doc, string element_name) {
    CComPtr<IXMLDOMElement> element;

    HRESULT hr = xml_doc->createElement((BSTR)element_name.c_str(), &element);

    if (FAILED(hr))
        hr_raise("Failed to create XML element '" + element_name + "'", hr);

    return element;
}

and use it like this:

void SomeClass::SomeMethod() {
    CComPtr<IXMLDOMElement> element = xmlh::create_element(xml_doc, "test");
    //..
    // save xml to file
}

is it ok? I mean can i return smart pointer as function result? Is this approach free from leaks?

2) Also i use some smartpointer as Class Members. Like this:

class XMLCommand {
    public:
        XMLCommand(std::string str_xml);
        ~XMLCommand(void);
    protected:
        CComPtr<IXMLDOMDocument> xml_doc;
}


XMLCommand::XMLCommand(string str_xml) {
    xml_doc = xmlh::create_xml_doc();
}

// some methods below uses xml_doc

The question is the same, is it correct and free from leaks?

Thanks.


Solution

  • That will work fine. When returning a smart pointer from function, the result is stored before the temporaries are destructed, so as long as you store it in a CComPtr<IXMLDOMElement> when you call create_element you will get the desired results (e.g., CComPtr<IXMLDOMElement> resElem = create_element(...);. Optimized C++ will very likely even not bother with temporaries and such and just use resElem instead of element inside your create_element() method, speeding up the process (google Return Value Optimization for details).

    The latter case is pretty much textbook smart-pointer usage. I can't think of a case that will fail. One danger when using smart pointers in general though is to be aware of and/or avoid circular dependencies, which can cause smart pointers to never delete their contained object.