【问题标题】:C++ shared_ptr reference count while binding another smart pointer to pointer returned by getC++ shared_ptr 引用计数,同时将另一个智能指针绑定到 get 返回的指针
【发布时间】:2019-06-19 07:51:58
【问题描述】:

根据“C++ Primer”第466页,将另一个智能指针绑定到get()返回的指针是错误的。接下来是一些代码和进一步的解释。我无法理解部分解释,逐字说明:

在这种情况下,p 和 q 都指向同一个内存。因为它们是相互独立创建的,所以每个引用计数为 1。当定义 q 的块结束时,q 被销毁。销毁 q 会释放 q 指向的内存。这使得 p 成为一个悬空指针,这意味着当我们尝试使用 p 时发生的事情是未定义的。

这个问题与我之前提出的问题Understanding C++ std::shared_ptr when used with temporary objects 相关,当时我正在玩弄自己的示例,并错误地认为在第 5 行创建了一个临时的shared_ptr

shared_ptr<int> p(new int(42));
int *q = p.get();
{ // new block
  // undefined: two independent shared_ptrs point to same memory
  shared_ptr<int>(q); 
  cout << p.use_count() << '\n' << q.use_count() <<'\n';
}
Output:
1
0

根据上面的解释,pq 的引用计数都是 1。

但是当添加一个打印语句来输出引用计数时。我知道p 的使用次数为 1,但 q 的使用次数为 0。q 的使用次数不应该为 1 吗?还是我错过了什么?如果 q 引用计数在块后为 0,我会理解。

【问题讨论】:

  • 问题在于作用域、内部作用域中的变量名隐藏以及声明变量的奇怪(但有效)语法。
  • 如果它是临时的,您的代码将无法编译,因为 q 将是 int*
  • @molbdnilo 它编译了godbolt.org/z/fPwchN 我预计会出现阴影,即使我不知道这可能会发生在不同的类型上
  • @Narase 它编译是因为没有临时的。 Here 是相同的代码,但有一个实际的临时代码。 ("error: request for member 'use_count' in 'q', which is non-class type 'int*'")

标签: c++ syntax expression shared-ptr declaration


【解决方案1】:

shared_ptr&lt;int&gt;(q);

这会创建一个名为 q 的 shared_ptr 并且等价于

shared_ptr<int> q;

它不指向任何东西,因此它的计数是 0

如果你想要第二个 shared_ptr 指向 q,你需要这个

 shared_ptr<int> p2(q); 

【讨论】:

  • 对不起,但这并不能回答我的问题,而且它似乎误解了我的问题。没有什么“我想要”,我的问题是为什么新创建的 shared_ptr q 引用计数为 0,而根据 C++ 入门它应该有引用计数 1。
  • @Sohof shared_ptr&lt;int&gt;(q);shared_ptr&lt;int&gt; q; 相同,即声明 shared_ptr 指向任何内容。
  • @Sohof 你误解了答案。当然你想要一些东西,它的第二个 shared_ptr 指向 q 并且你想知道为什么它的计数是 0。这是因为你从来没有链接它们,因为你创建了一个空的 shared_ptr,当然它的计数是 0,因为它没有指向任何东西
  • @Narase 所以你的意思是当这本书写“//未定义的两个独立的 shared_ptrs 指向同一个内存”并进一步销毁 q 时使 p 成为一个悬空指针,不知何故它们永远不会链接到首先?还有为什么书中说 q 的引用计数应该是 1 呢? (据我所知,Lippman 的 C++ Primer 应该是一本受人尊敬的书)。还是我还是误解了你的答案?
  • @Sohof 你 100% 确定你书中的那一行是 shared_ptr&lt;int&gt;(q); 吗?
【解决方案2】:

书中有一个错误-在内部块中,q 是一个空的shared_ptr,与p.get() 无关。

这似乎还没有进入任何已发布的勘误表。

以下内容应打印出您所期望的内容,并且与作者预期的一样未定义:

shared_ptr<int> p(new int(42));
{ 
  shared_ptr<int> q(p.get()); 
  cout << p.use_count() << '\n' << q.use_count() <<'\n';
}

【讨论】:

  • 我怀疑出了点问题,但不确定这是否是书中的错误。正如我链接到的关于这个主题的第一个问题所示,我最初认为正在创建一个临时文件,因为语法真的很相似。
猜你喜欢
  • 2020-07-10
  • 2012-05-25
  • 1970-01-01
  • 2014-05-30
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多