Modern C++:Efficient and Scalable Application Development
上QQ阅读APP看书,第一时间看更新

Returning References

Sometimes an object will be passed to a function and the semantics of the function is that the object should be returned. An example of this is the << operator used with the stream objects. Calls to this operator are chained:

    cout << "The value is " << 42;

This is actually a series of calls to functions called operator<<, one that takes a const char* pointer, and another that takes an int parameter. These functions also have an ostream parameter for the stream object that will be used. However, if this is simply an ostream parameter then it would mean that a copy of the parameter would be made, and the insertion would be performed on the copy. Stream objects often use buffering, so changes to a copy of a stream object may not have the desired effect. Further, to enable the chaining of the insertion operators, the insertion functions will return the stream object passed as a parameter. The intention is to pass the same stream object through multiple function calls. If such a function returned an object then it would be a copy and not only would this means that a series of insertions would involve lots of copies being made, these copies would also be temporary and so any changes to the stream (for example, manipulators such as std::hex) would not persist. To address these issues, references are used. A typical prototype of such a function is:

    ostream& operator<<(ostream& _Ostr, int _val);

Clearly you have to be careful about returning a reference since you have to ensure that the object lifetime lasts as long as the reference. This operator<< function will return the reference passed in the first parameter, but in the following code a reference is returned to an automatic variable:

    string& hello() 
{
string str ("hello");
return str; // don't do this!
} // str no longer exists at this point

In the preceding code, the string object only lives as long as the function, so the reference returned by this function will refer to an object that does not exist. Of course, you can return a reference to a static variable declared in a function.

Returning a reference from a function is a common idiom, but whenever you consider doing this make sure that the lifetime of the aliased variable is not the scope of the function.