c++ - lock() 和 expired() 有什么区别? weak_ptr C++

标签 c++ c++11 shared-ptr smart-pointers weak-ptr

最近我开始学习 C++11。 我研究了 weak_ptr。有两种获取原始指针的方法。

  1. lock() 函数

    shared_ptr<Foo> spFoo = wpPtr.lock();
    
    if(spFoo) {
        spFoo->DoSomething();
    }
    
  2. expired() 函数

    if(!wpPtr.expired())
    {
        shared_ptr<Foo> spFoo = wpPtr.lock();
        spFoo->DoSomething();
    }
    

哪种方法更好?这两种方式有什么区别?

最佳答案

所以 shared ptr 和 weak ptr 是线程安全的,因为如果你有一个给定线程本地对象的实例,并且它们共享一个共同的指向对象,你可以在一个线程和另一个线程中与它们交互,并且一切正常。

要使其正常工作,您必须正确使用它们。

wp.expired()仅对执行诸如“从缓冲区中删除每个过期的弱指针”之类的事情有用。它对您提出的目的没有用。

每个弱指针一旦过期,就会保持过期状态。但是,在您确认它已启用后,已启用的弱指针可能会立即过期。

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();
}

这是与弱指针交互的“正确”方式。测试弱指针的有效性,并在同一操作中获取共享指针。

创建 spFooif()之外 header 是可以接受的,我更喜欢这种技术作为 spFoo 的范围仅限于有效区域。

另一种首选技术是提前退出:

auto spFoo = wpPtr.lock();

if(!spFoo) return error("wp empty");

spFoo->DoSomething();

这使得代码的“预期”执行在一条直线上流动,没有缩进、条件或跳转。

关于c++ - lock() 和 expired() 有什么区别? weak_ptr C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37679636/

相关文章:

c++ - Qt GraphicsView mouseMoveEvent 阴影 GraphicsItem mouseMoveEvent

c++ - 自动克隆 unique_ptr

c++ - 为什么make_shared的大小是两个指针?

c++ - 如何将 boost::atomic_store 与 shared_ptr<T> 和 shared_ptr<const T> 一起使用?

c++ - 使用C++ shell()获取PID?

java - Delaunay 三角剖分中没有边的矩形约束

c++ - 通过引用数组传递堆栈分配的参数

C++11 文件流

c++ - token "<"之前的错误预期标识符

c++ - 在参数中移出的智能指针上调用方法是否安全?