The first is return by value, i.e. a copy of the value is returned.
The second returns a pointer, which presumably points to a string in memory somewhere.
The third returns a reference, which is similar to a pointer except, in general, has the semantics that you should assume the object is either allocated on the stack or is owned by some other object and therefore should not be freed.
Adding a const constraint to a pointer or reference is useful because code that receives the returned value is prevented from modifying the contents of the string or calling any of its methods that aren't themselves declared as const.
The point of this article is that when returning a copy of a value, it is largely pointless to prevent the caller from modifying the returned copy; and therefore that compilers should warn when this is done.
As some explanation, in C++ you have three general modes of returning a value:
The first is return by value, i.e. a copy of the value is returned. The second returns a pointer, which presumably points to a string in memory somewhere. The third returns a reference, which is similar to a pointer except, in general, has the semantics that you should assume the object is either allocated on the stack or is owned by some other object and therefore should not be freed. Adding a const constraint to a pointer or reference is useful because code that receives the returned value is prevented from modifying the contents of the string or calling any of its methods that aren't themselves declared as const.The point of this article is that when returning a copy of a value, it is largely pointless to prevent the caller from modifying the returned copy; and therefore that compilers should warn when this is done.