Archived

This topic is now archived and is closed to further replies.

sQuid

Returning a Reference

Recommended Posts

So I understand that you''d pass arguments by reference
some_function(Foo& bar);
 
to avoid making an extra copy of the argument. But, other than in member functions when you''re returning *this, when would you return by reference
Foo& another_function(Foo &bar)
 
since whatever the return value refers to will then be out of scope. Are there any other valid uses of returning a reference?

Share this post


Link to post
Share on other sites
You might want to return a reference to a member variable of a class.



"Absorb what is useful, reject what is useless, and add what is specifically your own." - Lee Jun Fan

Share this post


Link to post
Share on other sites
You can return a refernce to anything that is not local to your function. You could return a reference to a member variable :


class Foo
{
HugeObject bar;
public:

const HugeObject& Bar() const
{
return bar;
}

Foo& Bar( const HugeObject& val )
{
bar = val;
return *this;
}

friend std::ostream& operator<<( std::ostream&, const Foo& );
friend std::istream& operator>>( std::istream&, Foo& );
};


Note that returning a non-const reference to a member variable is a violation of encapsulation, as the receiver of the value could use it to modify the variable as if it were public - if that''s what you want, get over it and just make it public instead of fooling yourself.

You can also return a reference to a parameter, not necessarily *this, for example to enable call chaining.

With iostreams, you need to return the stream object by reference to allow calls like
std::cout << FooObj1 << FooObj2 << FooObj3 << std::endl;


std::ostream& operator<<( std::ostream& os, const Foo& obj )
{
os << obj.bar;
return os;
}

std::istream& operator<<( std::ostream& is, Foo& obj )
{
is >> obj.bar;
return is;
}


iostreams operator overloads are typically friend non-members of the class you are adding stream support for.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
You can also return a reference to a parameter, not necessarily *this, for example to enable call chaining.



Returning a reference to a parameter is only a good idea when the parameter is a reference itself. Otherwise it will reference the stack and something will more than likely get screwed up down the line.

Share this post


Link to post
Share on other sites
I wouldn''t mix the use of pointers and references in your code simply because of the rule that you cannot have a NULL reference. Doing this may result in hard to find bugs.

I don''t know what the confusion is. Just make both function void for the examples you have provided and store the value in bar. The function does not need to return anything, since as you are passing by reference between the pointers they are referencing the same region of memory:

void some_function(Foo& bar);
void another_function(Foo &bar);

Foo& bar and Foo &bar are parsed as the same thing.



Beginners and experts will find answers here.

Share this post


Link to post
Share on other sites
quote:
Original post by Mathematix
I wouldn''t mix the use of pointers and references in your code simply because of the rule that you cannot have a NULL reference. Doing this may result in hard to find bugs.



I don''t see the problem. To try and create a null reference, you would have first to dereference a null pointer. Which is not that hard to find.

Anyway returning *this by reference is a common C++ idiom, and that''s the only pointer I see discussed here.

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
quote:
Original post by Mathematix
I wouldn''t mix the use of pointers and references in your code simply because of the rule that you cannot have a NULL reference. Doing this may result in hard to find bugs.



I don''t see the problem. To try and create a null reference, you would have first to dereference a null pointer. Which is not that hard to find.

Anyway returning *this by reference is a common C++ idiom, and that''s the only pointer I see discussed here.


I don''t see the justification in doing this. Can you come up with a necessary, valid scenario?



Beginners and experts will find answers here.

Share this post


Link to post
Share on other sites
quote:
Original post by Mathematix
I don't see the justification in doing this. Can you come up with a necessary, valid scenario?



No problem, here's one : operator overloading.


class Foo
{
/* stuff */
public:
Foo() { /* stuff */ }
~Foo() { /* stuff */ }
Foo( const Foo& ) { /* stuff */ }

Foo& operator=( const Foo& )
{
/* stuff */
return *this;
}
};

Foo a, b, c;

...

a = b = c;


The principle of least surprise mandates that, since chained assignment is possible with basic types, user-defined types should provide it too.

It also lets you give a neater syntax to "accessors & mutators"


class Foo
{
int x, y, z;
public:
int X() const { return x; }
int Y() const { return y; }
int Z() const { return z; }

Foo& X( int new_x ) { x = new_x; return *this; }
Foo& Y( int new_y ) { y = new_y; return *this; }
Foo& Z( int new_z ) { z = new_z; return *this; }
};

Foo f;
f.X(10).Y(20).Z(30);
int x = f.X();


Like I'm telling you, it's a common C++ idiom. If you don't believe me, check any good reference book.

To conclude, I'll point out that I only know of one way to have a null this pointer, and if you get one that's because you really asked for it.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on August 14, 2003 6:00:56 PM]

Share this post


Link to post
Share on other sites
Fruny,

Typical of C++! The fuzzy standards say you can''t do something and it turns out there is a ''pseudo-way'' of doing it! LOL

I must play with this.

Beginners and experts will find answers here.

Share this post


Link to post
Share on other sites
quote:
Original post by Mathematix
Just make both function void for the examples you have provided and store the value in bar. The function does not need to return anything, since as you are passing by reference between the pointers they are referencing the same region of memory:



It wasn''t really a problem. I''d just seen functions returning references in Stroustrup and didn''t understand when it was appropriate and when it wasn''t.

Thanks for the replies.

Share this post


Link to post
Share on other sites