I’m sure you got this warm feeling after reading the previous section. The wonderful world of C++ programming has just revealed some of its secrets to you. You’re ready to improve the world and this example even further! Because really, is there any reason not to use a reference as a return value? No, there is not! Look at this:
Vec & sum(Vec & pos1, Vec & pos2) {
return pos1 + pos2;
}
5// someplace else
Vec p1(0.1, 0.3, 0.5);
Vec p2(1.9, 2.7, 0.5);
Vec p3 = sum(p1, p2);
10
But unfortunately… it is time to get back to reality. Because p3 is still a plain Vec, not a reference. You still need to copy the result:
So while you thought you were making your code faster, there is actually an extra step now. Life sucks, right?
But hey, why don’t we just declare p3 as a reference instead of a plain vec? This way, we can store the address instead of copying the values, right?
Think again. Variables are only valid within the scope they are declared. The result of the function sum is implicitly declared when you sum them up with the plus operator. This happens within the function itself. The result will run out of scope when the function is done, freeing all memory of local variables such as the result of the calculation.
In other words: you just passed an invalid address to your application, endangering the world while doing so. It’s a good thing the compiler will warn you about this, should you ever try.
So is there no way to use a return by reference? Well, there is. Just not to return a local variable. When you return an object which is actually stored in your class, there isn’t a problem. In fact, you’ve already used this:
Memc<Vec> points;
Vec & p = points.New();
p.x = 0.1;
...
5
This is just one example of when references are not only OK, but really needed. First off, the reference returned by new is not local to the method. The whole purpose of a memory container is to maintain a list of objects. Having the memory released when the function goes out of scope would not make any sense.
Also, suppose you don’t use a reference for p. You would be changing a copy instead of the object in the container. Without a reference, you would be unable to alter the objects inside the container.
Does this mean it can’t go wrong? Actually it can, but only if you’re really asking for it. For instance when you use a reference after deleting the object it references:
Memc<Vec> points;
Vec & p = points.New();
points.clear();
p.x = 0.1; // auch!
5
As a rule, try to use references only directly after creating them. If you reuse them later on, you’re asking for trouble.