我很清楚C ++ 11中的RAII模式和std::unique_ptr
以及其他“智能指针”,但是仍有一些情况我无法弄清楚如何在没有{的情况下很好地处理{1}}最后进行清理的部分。
具体来说,我正在考虑Windows编程,有时候我会想要泄漏句柄,有时我也不想。
如果我的功能看起来像他跟随的那样:
goto Cleanup
我真的没有看到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
后release()
使用unique_ptr
表示成功/告诉if
不要清理它。 (我可以为unique_ptr
创建一个特殊的删除器,以便正确清理窗口句柄。但是,我的问题是,对于我想将已分配的内存/句柄泄漏回调用者的情况,智能指针上的unique_ptr
使用“正确”吗?有没有更好的方法呢?返回release()
也可以,我想......
答案 0 :(得分:0)
如果要从函数中传递资源,则有两种情况:资源是可复制的(它具有可访问的复制构造函数)。
如果资源是可复制的(例如shared_ptr
),那么您只需将其复制到需要去的地方即可。当您的函数返回时,它只是您销毁的资源的副本。
如果资源不可复制(例如unique_ptr
),那么你需要移动它,这就是C ++ 11中move semantics的全部内容。
当您将资源移动到新位置时,旧位置变为空,因此当调用其析构函数时,无需执行任何操作。
如果您使用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_;
};