cppaddict posted:
I'd like to know what goes on under the hood when methods return
objects. Eg, I have a simple Point class with two members _x and _y.
It's constructor, copy constructor, assignment operator and additon
operator (which returns another Point object, and which my question is
about) are as follows:
Point:

oint(int x, int y) :
_x(x),
_y(y) { }
Point:

oint(const Point& p) {
_x = p._x;
_y = p._y;
}
Point& Point:

perator=(const Point& p) {
_x = p._x;
_y = p._y;
return (*this);
}
Point Point:

perator+(const Point& p) const {
Point ret(_x + p._x, _y + p._y);
return ret;
}
What happens when operator+ returns the temporary Point object that it
creates?
Does it use the copy constructor to create a copy of the temporary
variable "ret"? Is ret destroyed after that?
If not, how does it return a Point object?
Also, why is that "new" never comes into play? How can the compiler
know beforehand how many Point objects will be created via operator+?
Is it because such objects must exist in statements like:
Point p3 = p1 + p2;
I know this is a simple point, but I'm confused nonetheless.
Thanks for any clarification,
cpp
int Blah()
{
return 72;
}
int main()
{
int f = 45 + Blah();
}
When the end of Blah is reached, a temporary is created and this temporary
is given back to main. The temporary lives in main up until the next
semicolon, at which point it's destroyed.
Now, here's one that may result in an optimization:
int Blah()
{
int f = 76;
f *= 2;
f -= 4;
return f;
}
The compiler may choose to return a temporary, which has been copy-
initialized from "f", or it may return "f" itself. If it returns "f" itself,
then there's one less object created, and that's the optimization.
And another optimization:
int Blah()
{
int f = 76;
f *= 2;
f -= 4;
return f;
}
int main()
{
int x = Blah();
}
That x variable in main may be used in Blah, as no temporary is necessary.
And then there's functions that return references...
int k; //global
int& Blah()
{
k = 6783;
k *= 2;
k -= 64;
return k;
}
Here Blah is returning a reference to a global variable, so the global
variable will still exist after the end of Blah, and so it can be used in
main().
If, on the other hand, you do this:
int& Blah()
{
int k = 72;
return k;
}
The Blah function will in fact return a reference to k, but by the time you
get to use it in main, k no longer exists. Compilers warn whenever you
return a reference to a local variable.
And then there's binding to a const-reference:
int Blah()
{
int k = 72;
k +=4;
k *= 2;
return k;
}
int main()
{
const int& monkey = Blah();
//Here, the temporary returned from Blah (or its local variable)
//is directly bound to monkey
//The temporary does NOT get destroyed at the
//next semicolon, but at the end of the reference's
//scope, ie. the end of main
}
You may ask why one would bother binding to a const reference when they can
just do:
int main()
{
int monkey = Blah();
}
and rely on the optimization.
Well, there needn't be an optimization depending on the compiler, and so
monkey may be copy-constructed from the temporary returned by Blah(). Plus,
if Blah returns a const object, then "int monkey" won't optimize, because a
copy will have to be made to yield a non-const version. On the other hand
you could do "const int monkey".
Well anyway, take this code:
int Blah()
{
int k = 42;
k *= 2;
k += 4;
return k;
}
int main()
{
int monkey = Blah();
}
How many "int"s are made? Either 1, 2 or 3. The best compilers will only use
one int, the monkey from main. The monkey will be used in Blah, and then
when Blah finishes, a temporary *won't* be made, it'll just return its local
variable, which is monkey from main!
Another compiler may make 2 "int"s: the monkey in main, and the k in Blah.
The Blah function will return k directly.
And then ofcourse there's compilers that'll make 3 "int"s:
The monkey from main
k from Blah
The temporary returned from Blah
There's times when a function has no choice but to create a temporary to
return, eg.
int Blah()
{
int k = 7;
return k + 4;
}
But if you return the variable directly, and there's no constness problems,
then there's no problems with the actual local variable being returned.
All of these are just optimizations, and needn't be performed.
(Another even better compiler may turn the above function into:
int Blah()
{
int k = 7;
return k += 4;
}
And return "k" itself, as it can see that there's no consequences of adding
the 4 to k directly. One less temporary.
-JKop