57

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?

Barry
  • 286,269
  • 29
  • 621
  • 977
lqr
  • 987
  • 1
  • 8
  • 11
  • 8
    From your own quote: "[aliasing] is commonly used to point to member objects while owning the object they belong to." –  Nov 24 '14 at 16:23
  • you should be already familiar with aliasing because both C and C++ allow aliasing by default, even without considering `shared_ptr` you are already using a language which allows aliasing by default. – user2485710 Nov 24 '14 at 16:27
  • 1
    @hvd yes. I noticed this later after I posted this question. But it is still not specific enough. – lqr Nov 25 '14 at 01:14

1 Answers1

70

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.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • `but we also don't want the Foo to get deleted out from under us` that's a job for your `shared_ptr`, nothing really close to what the aliasing is for . – user2485710 Nov 24 '14 at 18:02
  • 2
    @user2485710 I think you're misunderstanding the question? The `shared_ptr` I created is actually sharing ownership with the `shared_ptr`. There's just one underlying object in all of this, but the aliasing constructor lets us have a `shared_ptr` that points to a member instead. – Barry Nov 24 '14 at 18:10
  • So, you mean in case you want to reset `f` but you don't want the object pointed by `f` destroyed because you're going to need its member object? Oh. Thanks a lot. I get it. q^.^p – lqr Nov 25 '14 at 03:22
  • So we could say that `specific_data` and `f` share the same resource, but the former's `operator->` actually gives you `bar` instead? – M.M May 29 '15 at 12:11
  • @MattMcNabb Yes, exactly. – Barry May 29 '15 at 12:15
  • 7
    Perhaps you can compare this with `struct A { int x; }; const int& x = A().x;`. In this case, the `A` object is kept alive aswell as long as the reference `x` exists. – Johannes Schaub - litb Feb 27 '16 at 12:21
  • @JohannesSchaub-litb Quite an interesting [related question](http://stackoverflow.com/q/35947296/2069064) to just that example... – Barry Mar 17 '16 at 22:44
  • 6
    Please bear in mind that `const` is necessary here. Regular reference won't extend temprorary's lifetime – Patryk Nov 15 '16 at 15:36
  • @Barry Can you show possible implementation of this constructor? – VINOTH ENERGETIC Apr 11 '17 at 10:17
  • Hi @Barry, I make [a similar test}(https://ideone.com/gr3ZSH), and seems that when I reset f, its `use_count` will be 0 rather than 1. Why this happen? – calvin Aug 20 '21 at 15:23