如果函数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/

10-13 05:11