Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++11 C+中更复杂的清理+;_C++11_Raii_Resource Cleanup - Fatal编程技术网

C++11 C+中更复杂的清理+;

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

我很清楚C++11中的RAII模式和
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_;
};