我在读这个,
http://www.informit.com/articles/article.aspx?p=31529&seqNum=5
作者还解释了三种智能指针设计(见文章末尾的图片)。
我相信现在的GCC,CLang,可能还有视觉C++都使用smart pointers with control block
。
我可以想象为什么没有使用intrusive reference counting
,但是第二个实现-- smart pointer with pointer to pointer block
有什么问题呢?应该有两个指针去引用,但智能指针对象的大小将只有一半.
带有控制块的智能指针
带指针块的智能指针
具有侵入性引用计数的智能指针
发布于 2015-08-24 16:19:01
一个重要的原因是性能,如果shared_ptr::get()
直接存储在shared_ptr
对象中,它不需要取消引用一个指针就可以找到对象地址。
但是除了性能之外,smart pointer with pointer to pointer block
实现不支持您可以使用shared_ptr
所做的所有事情。
std::shared_ptr<int> pi(new int(0));
std::shared_ptr<void> pv = pi;
std::shared_ptr<int> pi2 = static_pointer_cast<int>(pv);
struct A {
int i;
};
std::shared_ptr<A> pa(new A);
std::shared_ptr<int> pai(pa, pa->i);
struct B { virtual ~B() = default; };
struct C : B { };
std::shared_ptr<B> pb(new C);
std::shared_ptr<C> pc = std::dynamic_pointer_cast<C>(pb);
在这些示例中,pv
、pai
和pb
存储与控制块拥有的指针不同的指向类型,因此必须在shared_ptr
本身中存储第二个指针(可能是另一种类型)。
对于pv
和pb
,可以通过将存储在控制块中的指针转换为需要返回的类型来使其工作。这在某些情况下是可行的,尽管有一些使用多重继承的示例无法正确工作。
但是对于pai
示例(它使用别名构造函数),如果不将指针单独存储到控制块中的指针,就无法使其工作,因为这两个指针是完全无关的类型,您不能在它们之间进行转换。
你在评论中说:
我看到,对于make_shared,第二个指针指向分配块的内部地址。(实际上我已经试过了,似乎是这样的)
是的,没错。仍然有第二个指针,但这两个诗引用到相同的内存块。这样做的优点是只需要为对象和控制块分配一个内存,而不是两个单独的内存分配。此外,对象和控制块在内存中相邻,因此更有可能共享缓存线。如果CPU已经在其缓存中获得了参考计数,那么它可能也有它的缓存中的对象,因此访问这两个对象都更快,这意味着有另一个缓存行可用于其他数据。
https://stackoverflow.com/questions/31874669
复制相似问题