Q:

What are the alternatives to references and standard pointers for returning local variables in C++?

I am fairly new to C++ and I know of three ways of returning a local variable and all have their downsides:
Person& getPerson()
{
   Person bob;
   return bob;
}

Clearly not a good idea.
Person getPerson()
{
   Person bob;
   return bob;
}

No chance of a null pointer or dangling reference but a performance hit.
Person* getPerson()
{
   return new Person();
}

No chance of a null pointer but surely this violates the basic rules of OO design. Another object will have to delete this - but why should it have to? The implemenation of the getPerson() method has nothing to do with it.
So, I am looking for an alternative. I have heard of shared pointers and smart pointers (standard and Boost) but I'm not sure whether any of them are designed to deal with this problem. What do you guys suggest?

A:

Option #2: return by value.
Person getPerson()
{
  Person bob;
  return bob;
}

There is no performance hit here. This copy may be (and probably will be) elided by your compiler. In fact, even if you turn off your compiler's copy elision optimizations, with a C++11 compiler this will be considered as a move first.
In fact, even if you then do Person p = getPerson(), which would normally involve two copies, both may be elided.
See §12.9/31:

in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value

And §12.9/32:

When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.

A:

No chance of a null pointer or dangling reference but a performance hit.

Actually, no performance hit at all.
See for example here: Want Speed? Pass by Value.
Compiler can easily optimize that, with strategies called copy elision and the named return value optimization (check out the link for that).

A:

You shouldn't worry too much about a performance hit here:
Person getPerson()
{
   Person bob;
   return bob;
}

The copy you are worried about will most likely be elided in what is called return value optimization (RVO). The C++ standard allows compilers to make this optimization, even if it breaks the as-if rule. I haven't come across a compiler that wouldn't elide a copy in this kind of expression for a long time:
Person p = getPerson();

In C++11, even in the absence of copy elision, this would be a candidate for a move construction. This could be an extremely cheap operation, but that really depends on the type in question. In any case, copy elision is hard to avoid.
See this related post.
See this demo.

