从 weak_from_this() 获得的 weak_ptr 无效

weak_ptr obtained from weak_from_this() is invalid

这里是一个最小的重现示例:

源代码:

#include <memory>
#include <iostream>

class A : public std::enable_shared_from_this<A>
{
 public:
  A(std::weak_ptr<A> up) : up_(up)
  {
    std::cout << "A" << " has up_? " <<
        ((up_.lock()) ? "yes" : "no")
              << std::endl;
  }

  void grow()
  {
    if (dp_)
      dp_->grow();
    else
      dp_ = std::make_shared<A>(weak_from_this());
  }

 private:
  std::weak_ptr<A> up_;
  std::shared_ptr<A> dp_;
};

int main()
{
  auto wp = std::weak_ptr<A>();
  A a(wp);
  for (int i = 0; i < 3; ++i)
  {
    a.grow();
  }
  return 0;
}

原始日志:

clang++ minimal.cpp && ./a.out
A has up_? no
A has up_? no
A has up_? yes
A has up_? yes

期望的行为:

clang++ minimal.cpp && ./a.out
A has up_? no
A has up_? yes
A has up_? yes
A has up_? yes

其实我想知道为什么原始输出的第二行说'no'?我认为当我们第一次创建类型 A 的对象时(恰好在它的构造完成之后,并且在我们对其调用 grow() 之前),我们有一个有效的对象,我们可以将引用传递到我们想要的任何地方,不是吗?

来自cppreference,大约std::enable_shared_from_this::weak_from_this

Returns a std::weak_ptr<T> that tracks ownership of *this by all existing std::shared_ptr that refer to *this.

同时

A a(wp);

这不是任何 shared_ptr 跟踪的对象。它是一个具有自动存储持续时间的普通对象。如果你想让 weak_from_this 工作,必须有一个 shared_ptr 跟踪第一个对象。