std::shared_ptr 的“自有指针”和“存储指针”有什么区别?

Joh*_*ohn 7 c++ shared-ptr c++11

根据这个文档,它说(强调我的):

http://www.cplusplus.com/reference/memory/shared_ptr/owner_before/

与 operator< 重载不同,这种排序考虑了shared_ptr 拥有的指针,而不是存储的指针,如果这些对象中的两个被认为是等价的(即,无论操作数的顺序如何,此函数都返回 false),如果它们两者共享所有权,或者它们都为空,即使它们存储的指针值不同。

所述存储的指针(即,指针的shared_ptr对象解除引用到)可能不是在所有的指针(即,指针上物件破坏删除)如果对象的shared_ptr是一个别名(别名构造的对象和它们的副本)。

的“拥有的指针”和“存储的指针”有std::shared_ptr什么区别?

我将不胜感激能在这个问题上得到一些帮助。

这是一些相关代码(检查http://cpp.sh/27auqq):

// enable_shared_from_this example
#include <iostream>
#include <memory>

struct C : std::enable_shared_from_this<C> {int a; int b; };

int main () {
  std::shared_ptr<C> foo, bar;

  foo = std::make_shared<C>();

  bar = foo->shared_from_this();
  
  std::shared_ptr<int> p1(foo, &foo->a);
  std::shared_ptr<int> p2(foo, &foo->b);
  
  *p1=5;
  *p2=9;
  
  std::cout << p1.use_count() << std::endl;
  std::cout << foo->a << std::endl;
  std::cout << foo->b << std::endl;

  if (!foo.owner_before(bar) && !bar.owner_before(foo))
    std::cout << "foo and bar share ownership" << std::endl;
    
  if(!p1.owner_before(p2) && !p2.owner_before(p1))
    std::cout << "p1 and p2 share ownership" << std::endl;
    
    if(!p1.owner_before(foo) && !foo.owner_before(p1))
    std::cout << "p1 and foo share ownership" << std::endl;
      

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

4
5
9
foo and bar share ownership
p1 and p2 share ownership
p1 and foo share ownership
Run Code Online (Sandbox Code Playgroud)

Cal*_*eth 6

“拥有的指针”和“存储的指针”有std::shared_ptr什么区别?

任何时候使用构造函数时template< class Y > shared_ptr::shared_ptr( const shared_ptr<Y>& r, element_type* ptr ) noexcept;,您都会拥有与 共享所有权r但取消对*ptr.

例如之后

std::shared_ptr<std::pair<int, double>> pair = std::make_shared<std::pair<int,double>>(1, 2.);
std::shared_ptr<int> i(pair, &pair->first);
pair.reset();
Run Code Online (Sandbox Code Playgroud)

std::pair<int, double>保持活着i


cur*_*guy 1

为了支持诸如在不存在虚拟析构函数时将 a 转换为之shared_ptr<Derived>类的事情shared_ptr<Base>(在这种情况下是允许的,即使对于动态分配的类来说通常不是一个好主意),并且对于其他一些功能,shared_ptr需要有一个指向由该实例中的每个特定实例以及控制块中的另一个实例指定的对象的指针。使用控制块:

  • 用于计算“强引用”(由 管理的动态分配的已用资源的所有者shared_ptr)和“弱引用”(控制块的所有者,但不是受管理的已用资源的所有者);
  • 记住要删除什么(指向拥有的对象的指针)以及如何删除它。控制块保存传递给原始shared_ptr构造函数的确切指针值。

通常该值仅用于删除目的。仅当您使用 时才会检查(比较)其值owner_before所有其他函数检查每个实例中的指针shared_ptr,而不是控制块中的指针。