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