C++11 C+中更复杂的清理+;
我很清楚C++11中的RAII模式和C++11 C+中更复杂的清理+;,c++11,raii,resource-cleanup,C++11,Raii,Resource Cleanup,我很清楚C++11中的RAII模式和std::unique_ptr以及其他“智能指针”,但仍有一些情况,如果没有最后进行清理的goto Cleanup部分,我无法很好地处理 具体地说,我正在考虑Windows编程,有时候我想泄漏句柄,有时候我不想 如果我有一个函数,看起来有点像他,如下所示: PROCESS_INFORMATION p; if (!CreateProcess(... &p)) { throw windows_error(GetLastError()); } DWOR
std::unique_ptr
以及其他“智能指针”,但仍有一些情况,如果没有最后进行清理的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\u ptr
在这方面有什么帮助,除非我在unique\u ptr
上使用release()
,毕竟if
表示成功/告诉unique\u ptr
不要清理它。(我可以为unique_ptr
创建一个特殊的删除程序,以便它正确地清理windows句柄)。但是,我的问题是,在智能指针上使用release()
是否“正确”地将分配的内存/句柄泄漏回调用者?有更好的方法吗?返回一个共享\u ptr
也可以工作,我想…当您想从函数中传递资源时,有两种情况:资源是可复制的(它有可访问的复制构造函数)或不可复制
如果资源是可复制的(例如,shared\u ptr
),那么您只需将其复制到任何需要的地方即可。当您的函数返回时,只有您的资源副本被销毁
如果资源不可复制(例如,代码> UnQuyPPTR < /C>),那么您需要移动它,这是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;
}
当你说“泄漏给调用者”时,你是在谈论函数的返回值吗?在我的特殊情况下,现在,我正在将它保存到类中的私有句柄字段中。但是,是的,一般来说,我的意思要么是对调用方,要么是“函数作用域的生命周期”。代码下的描述听起来非常像著名的作用域卫士(Alexandrescu/Marginean)。但是C++11有更好的实现。但是,构建/使用一个只负责管理该流程资源的类可能更合适。移动应该是默认值,因为它通常比复制快,并且具有不同的含义(原始资源被重用)。另外,对于既不可复制也不可移动的资源,还有第三种情况,例如
std::mutex
(但这些情况不太常见)。@dyp我认为这不应该是默认情况。当我做a=b
时,我不会期望b
变成空的。这不是我的意思。OP有一个函数,它获取一个资源,并希望将该资源从那里获取(返回)。这应该通过移动默认值来完成。
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_;
};