Question about why is it necessary at all to return a reference from a function.
Following code behaves exactly the same, if we replace int& with
The difference is that, when you return a reference, you can assign to the result of GetVal():
myObj.GetVal() = 42;
You can also keep the returned reference around, and use it to modify myObj.val later.
If GetVal() were to return val by value, none of this would be possible.
Whether any of this is desirable, or indeed good design, is a different question altogether.
Note that your example is very different to the code in the linked question -- that code returns an invalid reference and is unequivocally a bad idea.