so what is the advantage of returning by reference over returning by value? |
Return by
non-const reference is common, and it tells the caller that the function-call expression itself is an lvalue. That's how you can implement operator[] to make something like
m[key] = value;
compile. Another common example are the I/O operators: they return ostream/istream by non-const reference so that they can be chained:
cout << a << b << c;
Return by const reference, as in your case, is not something I've seen much: it makes the function call a const lvalue, so the caller can take its address and it will be the address of the referenced object:
&rect.getWidth() == &rect.m_w;
. I suppose you could use it to call const member functions on the returned type without building a temporary.
a copy of the returned value is created somewhere, then it is copied into the receiving object, and then deleted from where it was stored. |
in most cases, it is unified with the receiving object, see for example
http://en.cppreference.com/w/cpp/language/copy_elision
In addition, since C++11 it is also guaranteed to be moved into the existing object where copy elision isn't possible but a move is.
do you know how its carried out wid = rect.m_w;.
The compiler performs some kind of memcpy? |
In this case (int) it will copy the value. Your main() does nothing so machine code won't be issued in any case, but had you done something with wid later (so that wid would have been assigned a CPU register), and had rect been in RAM, this would be a single CPU load instruction. Same as if you'd returned the int by value:
on Intel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
class Rectangle
{
public:
Rectangle(int w=0, int h=0) : m_w(w), m_h(h) {}
const int& getWidth() const { return m_w; }
int getWidthByValue() const { return m_w; }
private:
int m_w;
int m_h;
};
Rectangle rect;
int main()
{
volatile int wid = 0;
volatile int wid_by_value = 0;
wid = rect.getWidth();
wid_by_value = rect.getWidthByValue();
}
|
main:
movl rect(%rip), %eax
movl $0, -8(%rsp) // volatile int wid = 0
movl $0, -4(%rsp) // volatile int wid_by_value = 0
movl %eax, -8(%rsp) // wid = rect.getWidth();
movl %eax, -4(%rsp) // wid_by_value = rect.getWidthByValue();
xorl %eax, %eax
ret |