如何使 shared_ptr 的所有副本等于另一个 shared_ptr? [英] How to make all copies of a shared_ptr equal to another shared_ptr?

查看:38
本文介绍了如何使 shared_ptr 的所有副本等于另一个 shared_ptr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法解决这个问题.. 看起来我错过了一些简单的东西?我在 MakePointToSameValue 中放了什么,以便在 (1)

I cannot figure this out.. Looks like I'm missing something simple? What do I put in MakePointToSameValue so that at point (1)

  • b.ptr 和 c.ptr 都指向与 a.ptr 相同的内容
  • 换句话说,a.ptr.get() == b.ptr.get() == c.ptr.get()
  • b.ptr 和 c.ptr 最初指向的值被删除

?

struct Test
{
public:
  Test( int val ) :
    ptr( std::make_shared< int >( val ) )
  {
  }

  void MakePointToSameValue( Test& other )
  {
    //what do I put here?
    //other.ptr = this->ptr; //doesn't do it
  }

private:
  std::shared_ptr< int > ptr;
};

Test a( 0 );
Test b( 5 );
Test c( b );

b.MakePointToSameValue( a );

//(1)

复制 ptr 不起作用,因为它不会改变 c(嗯,c.ptr 的引用计数减少了 1).请注意,我使用 int 只是为了简单起见,但它应该适用于不可复制的类型.

Copying the ptr does not work, since it does not alter c (well, c.ptr has it's refcount decreased by one). Note that I use int just for simplicty, but it should work for noncopyable types.

为什么?我有一个表示值的类,任何类型的值,用于某种编译器.实际值及其存储方式在实例化时是已知的.唯一知道的是类型.因此,该类存储了一个 shared_ptr ,其中包含稍后确定的值的占位符(相当于在作为指针或引用传递时编译函数定义的参数:编译器只知道类型,仅此而已).在运行时,占位符应替换为实际值.

Why? I have a class representing values, any type of values, for use in a sort of compiler. The actual value, nor how it is stored, is known when it gets instantiated. The only thing known is the type. So the class stores a shared_ptr containing a placeholder for a value determined later on (corresponds to compiling the arguments of a function definition when passed as a pointer or reference: the compiler only knows type, nothing more). At runtime the placeholder should be replaced by an actual value.

编辑 新的一天开始,想出了这个.我知道这很简单.

Edit fresh start of the day, came up with this. I knew it was simple.

void MakePointToSameValue( Test& other )
{
  other.ptr.swap( ptr );
  ptr.reset();
  ptr = other.ptr;
}

现在的另一个问题是:对于任何符合标准的指针,上述操作是否能按预期工作?

Additional question now is: will the above work as expected for any standard compliant pointer?

推荐答案

此处您需要两个间接级别.虽然所有 shared_ptr 对象都指向一个包含计数和指向实际值的指针的公共元数据块是对的,但如果您尝试更新该块以指向不同的对象,您将d 现在有两个元数据块指向相同的值,每个块都有自己不同的引用计数概念.使用每个元数据块的 shared_ptr 对象都有正确的数量(从某种意义上说,它与引用计数相匹配),因此每个块的计数最终将达到零,但无法知道哪个块是达到零计数的最后一个块(因此应该删除该值).所以 shared_ptr 明智地不允许更改元数据内的对象指针.您只能将 shared_ptr 与新元数据块、新计数、新对象相关联.并且指向同一对象的其他指针不受影响.

You need two levels of indirection here. While you're right that all shared_ptr objects point to a common metadata block that contains the count and the pointer to the actual value, if you tried to update that block to point to a different object, you'd now have two metadata blocks pointing to the same value, each with their own different idea of what the reference count is. There's the right number (in the sense that it matches the reference count) of shared_ptr objects using each metadata block, so the count on each block will eventually reach zero, but there's no way to know which block is the last block to reach a count of zero (and hence should delete the value). So shared_ptr sensibly doesn't allow changing the object pointer inside the metadata. You can only associate the shared_ptr with a new metadata block, new count, new object. And other pointers to the same object aren't affected.

正确的做法是使用第二个间接层(shared_ptr>).这样一来,每个对象就只有一个元数据块和一个计数.您的更新发生在中间 shared_ptr.

The right way to do this is to use a second layer of indirection (shared_ptr<shared_ptr<int> >). That way there's exactly one metadata block and exactly one count for each object. Your update takes place to the intermediate shared_ptr.

这篇关于如何使 shared_ptr 的所有副本等于另一个 shared_ptr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆