【问题标题】:c++, msxml and smart pointersc++、msxml 和智能指针
【发布时间】:2012-08-13 21:26:12
【问题描述】:

我需要解析一些 XML 并编写一些帮助程序。我不是 C++ 专家,实际上我在七年前用 c 编写过。所以,我想确定,我使用的方法是正确的还是不正确的:)

1) 我实现了一些简单的助手,以处理异常。 例如:

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;
}

并像这样使用它:

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

还好吗?我的意思是我可以将智能指针作为函数结果返回吗?这种方法没有泄漏吗?

2) 我还使用一些智能指针作为类成员。 像这样:

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

问题是一样的,它是否正确且没有泄漏?

谢谢。

【问题讨论】:

  • HRESULT hr = xml_doc-&gt;createElement((BSTR)element_name.c_str(), &amp;element); => (BSTR)element_name.c_str() 对我来说看起来很可疑.. BSTR 基于带有长度前缀的WCHAR.. 而element_name 是string,通常使用char ..

标签: c++ visual-c++ smart-pointers msxml


【解决方案1】:

这样就可以了。从函数返回智能指针时,结果会在临时对象被销毁之前存储,因此只要在调用 create_element 时将其存储在 CComPtr&lt;IXMLDOMElement&gt; 中,您就会得到所需的结果(例如,CComPtr&lt;IXMLDOMElement&gt; resElem = create_element(...);。优化的 C++ 将很可能甚至不打扰临时人员等,只需在您的 create_element() 方法中使用 element 而不是 element,加快流程(详情请访问谷歌返回值优化)。

后一种情况几乎是教科书的智能指针用法。我想不出一个会失败的案例。但是,通常使用智能指针时的一个危险是注意和/或避免循环依赖,这可能导致智能指针永远不会删除其包含的对象。

【讨论】:

  • 非常感谢。我不考虑优化,它使用高负载第三方 API 的非常简单的控制台应用程序。客户端部分的简单代码对我来说比它的速度更重要。事实上,我对作业结果有疑问。我担心 CCompPtr 创建一个对象并且函数结果会重写它并且第一个对象被泄露。
  • 公平的担心——仅仅创建一个智能指针不会再创建一个对象的实例,就像Shape * pShape; 将创建一个Shape 对象一样。更重要的是,当您调用CComPtr&lt;IXMLDOMElement&gt; resElem = create_element(...); 时,您不是首先创建一个CComPtr 然后使用operator= 对其进行初始化,您实际上是在使用该类型的复制构造函数构造CComPtr&lt;&gt;!因此,即使出于某种疯狂的原因 CComPtr&lt;&gt; 的默认构造函数实例化了一个对象,在这种情况下您甚至都不会调用默认构造函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 1970-01-01
  • 2011-08-12
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多