0

我很清楚std::unique_ptrC++11 中的 RAII 模式和其他“智能指针”,但仍有一些情况我无法弄清楚如何在没有goto Cleanup最终进行清理的部分的情况下很好地处理。

具体来说,我正在考虑 Windows 编程,有时我会想要泄漏句柄,而其他时候我不会。

如果我有一个看起来有点像他的函数:

PROCESS_INFORMATION p;
if (!CreateProcess(... &p))
{
  throw windows_error(GetLastError());
}

DWORD r = WaitForSingleObject(h, 5000);
if (r == WAIT_TIMEOUT || r == WAIT_FAILED)
{
  // terminate process, close handles
  throw ...;
}

if (!SetEnvironmentVariable(...))
{
  // terminate process, close handles
  throw windows_error;
}

(a few other operations that if they fail i have cleanup to do).

return process handle;

我真的不知道如何unique_ptr在这里帮助我,除非我毕竟使用 therelease()来表示成功/告诉不要清理它。(我可以创建一个特殊的删除器,以便它正确清理 Windows 句柄)。但是,我的问题是,对于我想将分配的内存/句柄泄漏回调用者的情况,智能指针的这种用法是“正确的”吗?有更好的方法吗?退回罐头也可以,我想...unique_ptrifunique_ptrunique_ptrrelease()shared_ptr

4

1 回答 1

0

当您想从函数传递资源时,有两种情况:资源是可复制的(它具有可访问的复制构造函数)或不可复制。

如果资源是可复制的(例如shared_ptr),那么您可以简单地将其复制到它需要去的任何地方,然后您就完成了。当您的函数返回时,只有您的资源副本被销毁。

如果资源不可复制(例如unique_ptr),那么您需要移动它,这就是C++ 11 中移动语义的全部内容。

当您将资源移动到新位置时,旧位置变为空,因此当调用其析构函数时,无事可做。

如果你使用 传递资源return,那么你不需要做任何特别的事情,return如果可以的话会自动移动。

例如:

std::unique_ptr<resource> get_resource()
{
    std::unique_ptr<resource> result(new resource());

    if (result->is_something_wrong())
    {
        throw std::exception();
    }

    return result;
}

如果你想将资源传递给一个字段,或者类似的东西,那么你需要明确地说你想通过使用来移动它std::move

class resource_user
{
    void init_resource()
    {
        std::unique_ptr<resource> result(new resource());

        if (result->is_something_wrong())
        {
            throw std::exception();
        }

        resource_ = std::move(result);
    }

    std::unique_ptr<resource> resource_;
};
于 2014-04-21T11:50:36.277 回答