C ++ 11 Smart pointer accounting schema

I am reading this,
http://www.informit.com/articles/article.aspx?p=31529&seqNum=5
and the author explains three types of smart pointer design (see pictures at the end of the post).

I believe the current GCC, CLang and possibly Visual C ++ are using smart pointers with control block

.

I can imagine why intrusive reference counting

not used, but what is the problem with the second implementation - smart pointer with pointer to pointer block

? There should be two pointers, but the size of the smart pointer object will be half.

smart pointer with control unit

smart pointer with control unit

smart pointer with pointer to pointer block

smart pointer with pointer to pointer block

smart pointer with intrusive reference counting

enter image description here

+3


source to share


1 answer


One of the important reasons is performance, there is shared_ptr::get()

no need to look for a pointer to look up the address of an object if it is stored directly inside the object shared_ptr

.

But besides performance, the implementation smart pointer with pointer to pointer block

doesn't support everything you can do with shared_ptr

eg.

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);

      

In these examples pv

, pai

and pb

store a pointer that is not of the same type as a pointer belonging to the control unit, so there must be a second pointer (which may be of a different type) stored in itself shared_ptr

.

For pv

and, pb

one could make it work by converting the pointer stored in the control unit to the type that needs to be returned. This will work in some cases, although there are examples of using multiple inheritance that will not work correctly.



But for the example pai

(which uses the alias constructor) there is no way to make this work without storing a separate pointer in the control block, because the two pointers are completely unrelated types and you can't convert between them.

You said in a comment:

I see, and in the case of make_shared, the second pointer points to an address internal to the allocated block. (I actually tried it already and it seems this way)

Yes, that's right. There is also a second pointer, but both poitners refer to the same block of memory. This has the advantage that only one memory allocation is required instead of two separate ones for the object and the control unit. In addition, the object and the control block are contiguous in memory, so they are more likely to share a cache line. If the processor already has a reference count in its cache, then it probably also has an object in its cache, so accessing both of them is faster and means there is a different cache line for other data.

+2


source







All Articles