在C ++中进行更复杂的清理

时间:2014-04-19 19:14:12

标签: c++11 raii resource-cleanup

我很清楚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_ptrrelease()使用unique_ptr表示成功/告诉if不要清理它。 (我可以为unique_ptr创建一个特殊的删除器,以便正确清理窗口句柄。但是,我的问题是,对于我想将已分配的内存/句柄泄漏回调用者的情况,智能指针上的unique_ptr使用“正确”吗?有没有更好的方法呢?返回release()也可以,我想......

1 个答案:

答案 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_;
};