我可以记得std :: weak_ptr吗?

时间:2017-11-15 21:49:30

标签: c++ c++11 shared-ptr weak-ptr data-representation

首先,std::weak_ptr的典型实施是什么?特别是std::weak_ptr只是指向std::shared_ptr

的控制块的指针

如果所有std::shared_ptr引用都消失了,内部控制块是否已删除?如果是这样,如果重新使用该内存,std::weak_ptr::expired()如何正常运行?

我有一个包含std::weak_ptr的对象,我希望将memcpy对象提供给稍后要处理的缓冲区。这样做会以某种方式打破智能指针的内部工作吗?

1 个答案:

答案 0 :(得分:5)

当所有std::shared_ptr个对象都消失后,控制块仍然存在(std::weak_ptr的工作方式),只删除引用的对象。

现在,可以通过std::memcpy only if it is trivially copyable安全地复制C ++对象。检查TriviallyCopyable概念的要求,我们发现由于具有非平凡的复制构造函数,std::weak_ptr不满足它。实际上,这个构造函数会增加控制块内的弱指针计数器,因此用std::memcpy复制它会破坏它的不变量。

老实说,在普通代码中将std::weak_ptr存储在原始缓冲区中听起来很糟糕。缓冲区通常用于序列化,发送/写入数据等,所有这些任务对于智能指针都是无意义的。但是,如果您完全确定需要将其存储在缓冲区中,则需要placement new

std::weak_ptr<T> the_one_i_want_to_copy;

std::weak_ptr<T> * buffer = ...;
new (buffer) std::weak_ptr<T> { the_one_i_want_to_copy };

注意(buffer)之后的new:它告诉new不要分配内存,而是使用已准备好的地方(因此地方新建) 。准备buffer时,请务必提供所需的尺寸和对齐方式。