shared_ptr不增加引用计数,而是指向同一个地址

shared_ptr doesn't increase reference count, but point at the same address

这是我的代码片段:

#include <iostream>
#include <list>
#include <memory>

class A
{

 public:

  int a = 100;

  A()
  {
    std::cout << "Create A" << std::endl;
  }

  ~A()
  {
    std::cout << "Release A" << std::endl;
  }

  virtual void printer() = 0;

};

std::list<std::shared_ptr<A>> arr;

class B : public A
{

 public:

  int b = 1000;

  ~B()
  {
    std::cout << "Release B" << std::endl;
  }

  void printer() override
  {
    std::cout << "B's printer" << std::endl;
  }

  B()
  {
    std::shared_ptr<A> tmp(this);
    arr.push_back(tmp);
    (*arr.begin())->printer();
    std::cout << "inside B's c'tor test B counts: " << tmp.use_count()
              << std::endl;
  }

};

int main(int argc, char const *argv[])
{
  std::shared_ptr<B> B_ptr = std::make_shared<B>();
  std::shared_ptr<A> A_ptr(B_ptr);
  std::cout << "list address:  " << (*arr.begin()).get() << std::endl;
  std::cout << "test B address: " << B_ptr.get() << std::endl;
  std::cout << "test A address: " << A_ptr.get() << std::endl;

  std::cout << "list counts:  " << (*arr.begin()).use_count() << std::endl;
  std::cout << "test B counts: " << B_ptr.use_count() << std::endl;
  std::cout << "test A counts: " << A_ptr.use_count() << std::endl;
  return 0;
}

我的期望是:A的引用计数应该是3,但是只得到了2。我想当我push_back到链表的时候,应该有一个临时创建的share_ptr对象,即使是被销毁,列表中的那个也应该指向与 A_ptr 和 B_ptr 相同的地址。事实证明,他们(那三个)确实指向了同一个地址,但是 use_count 得到了不同的结果。 (*arr.begin()).use_count()是1,其他都是2。

为什么?请帮忙。

Ps:我知道把这个指针指向share_ptr是愚蠢的操作,但结果没有意义,甚至不符合语法。

My expectation is: A's reference count should be three, but only got 2.

你的期望是错误的。您只复制了一份共享指针,因此使用次数为 2。

std::shared_ptr<A> tmp(this);

在这一行中,您将不属于您的裸指针的所有权转移到一个新的共享指针中。因为它已经被另一个共享指针所拥有,所以当两个不同的所有者试图破坏它时,程序的行为将是不确定的。


可以使用 std::enable_shared_from_this 从中创建共享指针,但这并不简单。