【问题标题】:How to ensure (like a try-finally) destruction of a HEAP-ALLOCATED object如何确保(如最终尝试)销毁 HEAP-ALLOCATED 对象
【发布时间】:2011-08-31 00:30:37
【问题描述】:

我正在寻找一种方法来确保在堆上执行的对象在我完成后总是被释放。

我知道如果它是在堆栈上分配的,我可以使用 RAII 来确保它会得到处理 - 不幸的是,这对我不起作用(至少直接),因为有问题的对象实际上是通过调用创建的一个 api 函数,然后返回一个指向它在堆上创建的对象的指针。

所以,从概念上讲,我想做的是:

TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
try
{
    doStuffWithMyObjThatMayError(p_myObj);
}
finally
{
    delete p_myObj;
}

我唯一能想到的就是创建某种虚拟清理类,并在堆栈上创建该类的实例:

class MegaMaid
{
private:
    TheApi::ApiObject* toFree;
public:
    MegaMaid(TheApi::ApiObject* toFree)
    {
        this->toFree = toFree;
    }

    ~MegaMaid()
    {
        delete toFree;
    }
};

void doStuff()
{
    TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
    TheApi::ApiObject* p_myObj;
    MegaMaid cleaner(p_myObj);
    doStuffWithMyObjThatMayError(p_myObj);
}

有没有更好的方法来做到这一点?还是这是公认的解决方案?

【问题讨论】:

  • 您无法修复(损坏的)API?
  • 如果 API 函数返回一个指针,您是否 110% 确定可以在该指针上调用 delete? API 会这么说吗?还是提供了自己的清理功能?
  • Nemo - 不,我坚持使用 API。 =P
  • Kerrek - 是的,我很肯定。他们在他们提供的一些示例代码中正是这样做的......

标签: c++ heap-memory raii try-finally


【解决方案1】:

您仍然可以对函数返回的指针使用 RAII。您可以像这样使用智能指针(这正是您所描述的虚拟类):

std::unique_ptr<TheApi::ApiObject> p_myObj(TheApi::createAnApiObj());

【讨论】:

  • 嗯,谢谢...这似乎正是我要找的!
  • 所以我可能说得有点仓促......在我的特殊情况下,你实际上应该在 ApiObject 上调用一个 close 方法,然后删除它......我知道,糟糕的设计api方面,这应该在ApiObject的析构函数中处理......处理这种情况的标准方法是什么?
  • @PaulMolodowitch 使用自定义删除器。 std::unique_ptr&lt;T&gt; 实际上是 std::unique_ptr&lt;T, std::default_delete&lt;T&gt;&gt;,而 std::default_delete&lt;T&gt;::operator()(T* p);delete p;。您可以使用std::unique_ptr&lt;T, place_custom_deleter_here&gt; 来做您想做的事情来破坏时间。
【解决方案2】:

那个“虚拟类”被称为“智能指针”。您应该查看std::auto_ptrboost::shared_ptr。它们提供的正是您所需要的。

【讨论】:

    猜你喜欢
    • 2011-07-11
    • 1970-01-01
    • 2015-02-08
    • 2014-06-18
    • 2015-01-10
    • 2012-07-09
    • 2012-05-02
    • 2015-02-01
    • 1970-01-01
    相关资源
    最近更新 更多