safe std::tr1::shared_ptr usage

1.2k Views Asked by At

Is this approach unsafe?

#include <tr1/memory>

Foo * createFoo()
{
  return new Foo(5);
}

int main()
{
  std::tr1::shared_ptr<Foo> bar(create());

  return 0;
}

Or would it be preferable for createFoo to return a shared_ptr<Foo> object?

2

There are 2 best solutions below

0
On BEST ANSWER

The example is safe: if the shared_ptr constructor throws an exception, it delete's its pointer argument before throwing (draft standard, 20.9.11.2.1).

Whether create should return a shared_ptr depends on what its clients may reasonably want to do with its result. If all they ever do is wrap it in a shared_ptr, then return that for extra safety. (Yes, shared_ptr may introduce some coupling.)

7
On

Your example is safe the way you've written it. However, you could make it even more leak-proof by having your factory method createFoo() return an auto pointer instead of a raw pointer. That way you are guaranteed that there will be no leaks.

So what you'd get is:

#include <memory>
#include <tr1/memory>

std::auto_ptr<Foo> createFoo()
{
  return std::auto_ptr<Foo>(new Foo(5));
}

int main()
{
  std::tr1::shared_ptr<Foo> bar(createFoo());

  return 0;
}

It is of course also possible to have your factory method return a shared_ptr, but this might be seen as overkill, since the returned pointer will generally go out of scope quite quickly, since it will be used in an assignment or constructor. Furthermore, using auto_ptr states the intended use of the pointer more clearly, which is always a plus when people unfamiliar with your code have to understand it.