How to make all copies of a shared_ptr equal to another shared_ptr?

强颜欢笑 提交于 2019-12-06 11:19:08

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.

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.

Well, as far as I understand your requirements, shared_ptr does not contain any such mechanism; nor would any regular type. If you want this behaviour, you'll have to code it yourself. My suggestion: add a private static std::list<std::weak_ptr<Test>> registry; register each Test instance by adding it to the registry list in the constructor, and make sure to remove it in the destructor.

Then use that registry in MakePointToSameValue to iterate through all instances and reset the value of ptr.

If you're interested in efficiency and have a bit more instances than three, you'll want to replace the list with an unordered_set; and perhaps use unique_ptr rather than shared_ptr in your Test class.

Answer to additional question: no, it won't work. Look at the documentation of reset(): it resets one particular instance shared_ptr: it does nothing with (and knows nothing of) any other instances. When the reference count in the control block reaches zero, it additionally destroys the pointee, but that's it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!