Smart Pointers and Heirloom Underpants

batman

I’ve seen a lot of descriptions of scoped_ptr and unique_ptr, but often they don’t give clear examples of when to use one vs. the other. Hopefully this will clear things up.

unique_ptr is like an heirloom ring: you might purchase it, have it all your life, and end up being buried with it. For example, something like:

void Human::Life() {
  std::unique_ptr<Ring> ring(new Ring());
  // Leaving the scope is "dying" and the ring is destroyed
}

However, you could also pass it on to a child. For example:

void Human::Life() {
  std::unique_ptr<Ring> ring(new Ring());
  // Allocates a new child on the heap that will outlive this
  Kid *kid = CreateChild(this, GetSpouse());
  kid->Inherit(ring.release());
}

Now the parent’s life can end and the ring will survive.

On the other hand, scoped_ptr is more like “my underpants will die with me.” There is no passing them on. The intended use is something like:

void Human::Life() {
  scoped_ptr<Underpants> underpants(new Underpants());
  for (int i = 0; i < 1000; i++) {
      SendToCleaners(underpants.get());
  }
}

You might lend them out, but you retain ownership. Say you try to pass it on anyway with something like:

void Human::Life() {
  scoped_ptr<Underpants> underpants(new Underpants());
  Kid *kid = CreateChild(this, GetSpouse());
  kid->Inherit(underpants.get());
}

At the end of Life(), the underpants will be destroyed and any pointers to them will now point to garbage. Which makes sense, since they’re pointing to a dead guy’s underpants.

Finally, there’s shared_ptr, which is more like your award-winning chili recipe. If you tell a bunch of people about it then you’re sharing ownership of the chili recipe. Eventually all of you will die and the knowledge will be gone but you don’t know who’s going to the big chili pot in the sky in what order, so the data isn’t destroyed until you’re all gone.

kristina chodorow's blog