"owned pointer" 和 std::shared_ptr 的 "stored pointer" 有什么区别?

What is difference between "owned pointer" and the "stored pointer" for std::shared_ptr?

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

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

Unlike the operator< overload, this ordering takes into consideration the shared_ptr's owned pointer, and not the stored pointer in such a way that two of these objects are considered equivalent (i.e., this function returns false no matter the order of the operands) if they both share ownership, or they are both empty, even if their stored pointer value are different.

The stored pointer (i.e., the pointer the shared_ptr object dereferences to) may not be the owned pointer (i.e., the pointer deleted on object destruction) if the shared_ptr object is an alias (alias-constructed objects and their copies).

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

这是输出:

4
5
9
foo and bar share ownership
p1 and p2 share ownership
p1 and foo share ownership

What is the difference between "owned pointer" and the "stored pointer" for 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();

std::pair<int, double>i

维持生命

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

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

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