When is it required to return a reference from a function?
My question is when does any one need to return an object by reference? Well this comes from the fact that we开发者_如何学Go can as well pass the object to be filled through the parameter list itself. Are there any particular scenarios where it mandates the return by reference.
I'm asking this with respect to non member functions.
Edit: I'm aware of its usage in operator overloading.
You need to return as reference when you want the reveiving end to have access to the referred object. Consider operator[]
in a map and the use case:
std::map<std::string, int> word_count;
std::string word;
while ( std::cin >> word ) {
word_count[ word ]++;
}
You do not want to extract the value from the map, but rather access the stored object in this case to modify it. The same goes with many other designs, where you need access to some internal data, but you do not want to copy it:
if ( person.name() == "Pete" ) {
The user does not need to copy the object, only to check whether the object has a concrete value. You could have forced a copy by returning by value, and the semantics would be the same, but with higher costs. Or you could create a local variable and pass it by reference to a function that will fill it, in which case you are not only incurring the cost of copying, but also making code more cumbersome:
std::string name;
person.fill_name( name );
if ( name == "Pete" ) {
Which, as you can probably notice, is much more cumbersome in all uses of the member function.
Now, I see the "I'm asking this with non-member functions", well, the same rationale applies at different levels. Free standing functions can be applied to objects, consider:
boost::any any = 5;
boost::any_cast<int&>( any )++;
The function any_cast
is a free function and yet it returns a reference to another instance. If you need access to the actual object and not a copy, then a reference is the solution. Note that for only reading you don't need a reference and you may as well return by value:
std::cout << boost::any_cast<int>( any ); // will print 6 now
Similarly in all cases where the function returns references to objects that are not arguments, but globals or static
(returning a reference to a variable with auto storage in a function is undefined behavior, but in all cases where it is correct to do so the semantics would not be the same if you change it with any other solution.
When returning a reference to an object that exists elsewhere, for example a find
function searching a table.
You can also use it for a singleton (static object that is created once, and released after the main()
. For example :
struct A
{
unsigned int veryLongTable[ 1000 ];
};
const A& GetTable()
{
static A *table = NULL;
if ( NULL == table )
{
table = new A;
// write values
}
return *table;
}
Emphasis mine in quotes
we can as well pass the object
- What if the type is not default constructible?
- What if it is not constructible at all?
- What if it is constructible but extremely expensive to do so?
the object to be filled
You got it wrong: a function that returns by value can be equivalent to a function that uses a reference out parameter, but it's not equivalent to a function that returns a reference. To wit:
T& f();
void f(T&);
// We're not filling anything at all!
f().some_member();
f( ??? );
精彩评论