c++ - 当函数获得 unique_ptr 的所有权抛出异常时对象销毁

标签 c++ c++11 unique-ptr

如果函数 Foo()std::unique_ptr 的所有权转移给函数 Bar() 并说 Bar() 抛出异常,std::unique_ptr 中包含的对象将被销毁。

如何处理 Foo() 在这种情况下可能希望保留所有权的情况。

class A
{
public:
    std::unique_ptr<SomeData> getSomeData(...);
};

class B
{
public:
    pushToQ(std::unique_ptr<SomeData>);
    doSomething()
    ...
    popFromQ();
    ...
};

现在,如果 B::pushToQ() 抛出 QueueFullException,我将丢失 getSomeData() 生成的数据,这可能是我不想要的。

最佳答案

您要么转让所有权,要么不转让。如果你想转移,那么你不应该关心 Bar 是否可以抛出并杀死你的对象:

// i do not care what bar does with ptr, i am done with it
bar(std::move(ptr));

如果您可能想保留所有权也许,那么转让所有权是错误的解决方案。要么你想通过引用传递你的 unique_ptr,或者可能只是提取原始指针,或者甚至可能只是使用 shared_ptr。这取决于您的用例。但是没有中途所有权转移。

这里有一些例子。首选哪个完全取决于您:

bar(std::unique_ptr<Data>& ptr) {
    // not transferring, caller still owns the data
    something_that_might_throw();
    something_that_might_not();

    // ok got here?
    std::unique_ptr<Data> myPtr = std::move(ptr);
    // MINE NOW!!!
}

以上是“以异常安全的方式将 unique_ptr 移动到容器中并强烈保证系统不会被破坏的唯一异常安全解决方案”(来自 MGetz)

或者:

bar(Data* ptr) {
    // it really doesn't matter, caller always owns the data
    // just don't go doing something like this

    std::unique_ptr<Data> awful_idea(ptr);

    // now two separate people both think they own the data
    // and will both try to delete it. That'll work the first time...
}

或者一个更好的版本,这样你就不会把它搞砸,除非你非常努力地尝试

bar(Data& data) {
    // well clearly the caller owns it
}

或者:

bar(std::shared_ptr<Data> ptr) {
    // we both share the data
    // it won't get deleted until both bar() and caller delete it
}

关于c++ - 当函数获得 unique_ptr 的所有权抛出异常时对象销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26914534/

相关文章:

c++ - 如何在 C++ 中创建临时目录?

c++ - 变量的指针和 cout 地址

templates - 可变参数函数(不带参数!)

c++ - 是否可以在不向函数传递参数的情况下获取函数的返回类型?

C++ : Handle thread-local object destruction

c++ - 为什么 unique_ptr<Derived> 隐式转换为 unique_ptr<Base> ?

c++ - #ifdef VALUE 与 #if Defined (VALUE) 之间有什么区别

c++ - 在成员为 const 和列表初始化的情况下,对非静态成员的使用无效?

c++ - 在循环中将相同的 unique_ptr 移动到函数中

c++ - C++中的字符串比较