In this page (http://www.cplusplus.com/reference/memory/shared_ptr/), paragraph 5, it says:
Additionally, shared_ptr objects can share ownership over a pointer while at the same time pointing to another object. This ability is known as aliasing (see constructors), and is commonly used to point to member objects while owning the object they belong to. Because of this, a shared_ptr may relate to two pointers:
A stored pointer, which is the pointer it is said to point to, and the one it dereferences with operator*.
An owned pointer (possibly shared), which is the pointer the ownership group is in charge of deleting at some point, and for which it counts as a use.
Generally, the stored pointer and the owned pointer refer to the same object, but alias shared_ptr objects (those constructed with the alias constructor and their copies) may refer to different objects.
Then I read this page (http://www.cplusplus.com/reference/memory/shared_ptr/shared_ptr/) about the aliasing constructor of shared_ptr. But I still think this "aliasing" behavior confusing. Why is it here? What is it for? In what situation would I want this feature?
By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).
make_shared can allocate a single block of memory to hold both of these; constructing a shared pointer from a pointer to an already-allocated object will need to allocate a second block to store the reference count.
A std::shared_ptr consists of a control block and its resource. Yes, the control block is thread-safe; but no, the access to the resource is not thread-safe. That means, modifying the reference counter is an atomic operation and you have the guarantee that the resource will be deleted exactly once.
The shared_ptr class template stores a pointer to a dynamically allocated object, typically with a C++ new-expression. The object pointed to is guaranteed to be deleted when the last shared_ptr pointing to it is destroyed or reset.
Simple example:
struct Bar { // some data that we want to point to }; struct Foo { Bar bar; }; shared_ptr<Foo> f = make_shared<Foo>(some, args, here); shared_ptr<Bar> specific_data(f, &f->bar); // ref count of the object pointed to by f is 2 f.reset(); // the Foo still exists (ref cnt == 1) // so our Bar pointer is still valid, and we can use it for stuff some_func_that_takes_bar(specific_data);
Aliasing is for when we really want to point to Bar
, but we also don't want the Foo
to get deleted out from under us.
As Johannes points out in the comments, there is a somewhat equivalent language feature:
Bar const& specific_data = Foo(...).bar; Bar&& also_specific_data = Foo(...).bar;
We're taking a reference to a member of a temporary, but the temporary Foo
is still kept alive as long as specific_data
is. As with the shared_ptr
example, what we have is a Bar
whose lifetime is tied to a Foo
- a Foo
that we cannot access.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With