最近,我开始使用C++ 11。
我研究了weak_ptr
。有两种获取原始指针的方法。
lock()
函数shared_ptr<Foo> spFoo = wpPtr.lock();
if(spFoo) {
spFoo->DoSomething();
}
expired()
函数if(!wpPtr.expired())
{
shared_ptr<Foo> spFoo = wpPtr.lock();
spFoo->DoSomething();
}
哪个更好?两种方式有何不同?
最佳答案
因此,共享的ptr和弱的ptr是线程安全的,因为如果您具有给定线程本地的对象实例,并且它们共享一个公共(public)的指向对象,则可以在一个线程中与另一个线程进行交互,并且一切正常。
为了使其正常工作,您必须正确使用它们。wp.expired()
仅可用于执行“从缓冲区中删除每个过期的弱ptr”之类的操作。它对于您放置它的目的没有用。
每个弱指针一旦过期,仍保持过期。但是,在您确认已启用后,已启用的弱指针可能立即失效。
if(!wpPtr.expired()) {
// <<--- here
shared_ptr<Foo> spFoo = wpPtr.lock();
spFoo->DoSomething();
}
在<<--- here
中,我们对多线程环境中wpPtr
的状态一无所知。它可能已过期或未过期。另一方面:if(wpPtr.expired()) {
// <<--- there
}
在<<--- there
中,我们知道弱指针已过期。与文件io和其他类型的“事务”操作一样,检查是否可以执行某项操作的唯一方法是尝试执行该操作。在确定应该能够执行和执行之间,状态可能会更改,操作可能会失败。
有时您会发现自己几乎可以肯定无法尽早完成任务,这有时很有用,但不能确定您可以尝试完成。尝试尝试可能会失败,此时您将处理错误。
if(auto spFoo = wpPtr.lock()) {
spFoo->DoSomething();
}
这是与弱指针交互的“正确”方法。测试弱指针的有效性,并在同一操作中获取共享指针。在
spFoo
header 之外创建if()
是可以接受的,我更喜欢这种技术,因为spFoo
的范围完全限制在有效范围内。另一个首选技术是提早退出:
auto spFoo = wpPtr.lock();
if(!spFoo) return error("wp empty");
spFoo->DoSomething();
这使得代码的“预期”执行在没有缩进或条件或跳转的情况下排成一行。