return AnotherObject();
creates an object which is destroyed before function exit - temporaries are destroyed at the end of the expression that contains them[*], and the expression AnotherObject()
creates a temporary.
Since the function returns by reference, this means that by the caller even gets a chance to see that reference, it no longer refers to a valid object.
It would be OK if the function were to return by value, since the temporary would be copied[**].
[*] With a couple of situations that don't, but they don't help you here.
[**] Actually there's an optimization called "copy constructor elision" which means the temporary needn't be created, copied and destroyed. Instead, under certain conditions the compiler is allowed to just create the target of the copy in the same way it would have created the temporary, and not bother with the temporary at all.