当前位置:  开发笔记 > 编程语言 > 正文

为什么在std :: shared_ptr实现中需要两个指向托管对象的原始指针?

如何解决《为什么在std::shared_ptr实现中需要两个指向托管对象的原始指针?》经验,为你挑选了1个好方法。

这里引用了cppreference的实现说明部分std::shared_ptr,其中提到有两个不同的指针(如粗体所示):可以返回的指针get(),以及控制块中保存实际数据的指针.

在典型的实现中,std::shared_ptr只保留两个指针:

    存储的指针(返回一个get())

    指向控制块的指针

控制块是一个动态分配的对象,它包含:

    指向托管对象的指针或托管对象本身

    删除(类型擦除)

    分配器(类型擦除)

    数量shared_ptrs是自己的管理对象

    的数目weak_ptrs引用该管理对象

shared_ptr直接保持的指针是由返回get()的指针,而控制块保持的指针或对象是当共享所有者的数量达到零时将被删除的指针或对象.这些指针不一定相等.

我的问题是,为什么托管对象需要两个不同的指针(两个粗体)(除了指向控制块的指针)?那个回来的人get()不够吗?为什么这些指针不一定相等?



1> Reinstate Mo..:

这样做的原因是你可以拥有一个shared_ptr指向别的东西而不是它拥有的东西,这是设计的.这是使用列为nr的构造函数实现的.8关于cppreference:

template< class Y >
shared_ptr( const shared_ptr& r, T *ptr );

一个shared_ptr与此构造函数创建共享所有权r不过分ptr.考虑这个(人为的,但是说明性的)代码:

std::shared_ptr creator()
{
  using Pair = std::pair;

  std::shared_ptr p(new Pair(42, 3.14));
  std::shared_ptr q(p, &(p->first));
  return q;
}

一旦此函数退出,只有指向该int对子对象的指针可用于客户端代码.但由于之间的共享所有权qp,指针q"保持活着"整个Pair对象.

一旦发生了交易,就Pair必须将整个对象的指针传递给删除器.因此,指向Pair对象的指针必须存储在删除器旁边的某个地方 - 换句话说,在控制块中.

对于一个不那么人为的例子(可能甚至更接近该特征的原始动机),考虑指向基类的情况.像这样的东西:

struct Base1
{
  // :::
};

struct Base2
{
  // :::
};

struct Derived : Base1, Base2
{
 // :::
};

std::shared_ptr creator()
{
  std::shared_ptr p(new Derived());
  std::shared_ptr q(p, static_cast(p.get()));
  return q;
}

当然,真正落实std::shared_ptr已制定的所有隐式转换,这样的p-和- q舞蹈creator是没有必要的,但我已经把它有类似于第一个例子.


我认为这个例子足够好了.关键是我们指向一个作为原子实体管理的东西的一部分,而一对可能是最微不足道和明确的例子.这里的继承只是"成为某事的一部分"的一种特殊形式.
从派生类到基类的转换不是一个例子.
推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有