0
votes

There are two concepts (ownership, lifetime) that are important when using C++ smart pointers (unique, shared, weak). I try to understand those concepts and how they influence smart pointer (or raw pointer) usage.

I read two rules:

  1. Always use smart pointers to manage ownership/lifetime of dynamic objects.
  2. Don't use smart pointers when not managing ownership/lifetime.

An example:

class Object
{
   public:
      Object* child(int i) { return mChildren[i]; }
      // More search and access functions returning pointers here

   private:
      vector<Object*> mChildren;
};

I want to rewrite this using smart pointers. Lets ignore child() first. Easy game. A parent owns its children. So make mChildren a vector of unique_ptr.

According to the above rules, some people argue child(i) should continue returning a raw pointer.

But isn't this risky? Someone could do stupid things like deleting the returned object getting a hard to debug crash... which could be avoided using a weak_ptr or a shared_ptr as a return value.

Can't one say that copying a pointer always means to temporarily share the ownership and/or to assert the lifetime of the object?

Is it worth using smart pointers for children only if I do not get a safer API as well?

1

1 Answers

0
votes

You could return a const std::unique_ptr<Object>& which would allow you to have same semantics of a raw pointer to call methods on it while preventing deletion.

Using std::unique_ptr with raw pointer makes sense when you know that the ownership will survive any raw pointer and you are sure that people won't try to delete the pointer directly. So that's different from using a std::weak_ptr and std::shared_ptr because they won't allow you to use dangling pointers at all.

There's always room to make something wrong, so the answer really depends on the specific situation, where this code is going to be used and such.