Reputation: 6883
Here is an example for friend functions found on the internet:
#include <iostream>
using namespace std;
class Rectangle {
int width, height;
public:
Rectangle() {}
Rectangle(const Rectangle &r) {
width = r.width;
height = r.height;
cout << "copy\n";
}
Rectangle (int x, int y) : width(x), height(y) {}
int area() {return width * height;}
friend Rectangle duplicate (const Rectangle&);
};
Rectangle duplicate (const Rectangle& param)
{
Rectangle res;
res.width = param.width*2;
res.height = param.height*2;
return res;
}
int main () {
Rectangle foo;
Rectangle bar (2,3);
foo = duplicate (bar);
cout << foo.area() << '\n';
return 0;
}
Output:
24
Notice that the friend "duplicate" function creates a local variable and returns as return value to the caller. Isn't this supposed to be a local variable and is allocated on this stack? Should not it be destroyed once "duplicate" finishes execution? Is this example good?
Thanks.
Upvotes: 3
Views: 195
Reputation: 14708
Your function return Rectangle by value , so it should be fine.
Rectangle duplicate (const Rectangle& param)
The returned object isn't located in same storage isn't same object as one declared by local variable from abstract level of language. De-facto, as Justin says, compiler may optimize out creation of temporal object.
You would be in red, if you declared
Rectangle& duplicate (const Rectangle& param)
then function would try to return a reference to local variable.
How code is written, it is an equivalent of expression.
return Rectangle(param.width*2, param.height*2);
Copy constructor:
Rectangle(const Rectangle &r) {
width = r.width;
height = r.height;
}
should be proprly written as
Rectangle(const Rectangle &r): width(r.width), height(r.height)
{
}
The ouput line is a side-effect that might be omitted due copy elision.
Upvotes: 3
Reputation: 37317
Just think of regular types:
int getInt(void) {
int a = 5:
return a;
}
The function does not really return the local variable a
. Instead it returns a copy of a
. Similarly, res
is not returned by the function, but its copy.
In practice, the compiler is likely to detect your function and optimize the function by avoiding copying Rectangle
.
To observe the constructor calls, compile it with
g++ -fno-elide-constructors foo.cpp -o foo
You must disable return value optimization for g++ (-fno-elide-constructors
), which is a very basic optimization that'll be turned on even with -O0
.
Upvotes: 10