9.4 C FUNCTIONS RETURNING REFERENCE TYPES


9.4 C++ FUNCTIONS RETURNING REFERENCE TYPES

This section addresses the following question: What exactly is returned by a function whose return has been specified as non-void? Is it a local object itself, or is it a copy of the local object? To illustrate this question with a simple example, suppose we have the situation depicted in the following program where main calls a function f in line (B), the function being defined in line (A):

 
//CopyOnReturn.cc #include <iostream> #include <string> using namespace std; class User { public: string name; int age; User(string nam, int yy) { name = nam; age = yy; } }; User f(User usr) { return usr; } //(A) int main() { User u("Xino", 120); User y = f(u); //(B) cout << y.name << endl; // Xino return 0; }

The function f(User) in line (A) is passed an argument by value. Therefore, when this function is called by main in line (B), a copy of the object u will be constructed elsewhere in the memory and this copy will become the local object User inside the function f. When f executes its return statement, we are faced with the question: Is f returning the local object usr or a copy of usr? Said another way, Is the User object y in main going to be the same as what was the local object usr inside f or a copy of that object?

In the code as written above, what the function f returns is a copy of the local object it is supposed to return. Therefore, the program will make a copy of the argument object when it invokes the function f and then another copy of that copy when it executes its return statement. That can amount to a lot of copying for large objects. We have already seen how this copying can be eliminated when passing an argument to a function-by using either a reference parameter or a pointer parameter. But what about "copy on return?" That copying can be eliminated by declaring the return type to be a reference, as we do in the following version of the above program:

 
//NoCopyOnReturn.cc #include <iostream> #include <string> using namespace std; class User { public: string name; int age; User(string nam, int yy) { name = nam; age = yy;} }; User& f (User& usr) { return usr; } //(A) int main() { User u("Xino", 120); User y = f(u); //(B) cout << y.name << endl; // Xino return 0; }

In line (A), we have changed the parameter type and the return type to references. This suppresses the object copying involved in passing the argument to the function and in the function returning the object. When using a reference for a return type, it is an error to return a reference to an object that is local to a function. That should explain why we made the function parameter in line (A) a reference also.

In the program shown above, if we also wanted to guarantee that the object being passed to the function in line (A) would not get corrupted inside that function, we could use the following version of the program where the parameter in line (A) has now been declared to be a const reference. But, for reasons we will explain later, that makes it necessary for the return type to be a const reference also.

 
//ConstRefReturn.cc #include <iostream> #include <string> using namespace std; class User { public: string name; int age; User(string nam, int yy) { name = nam; age = yy; } }; const User& f(const User& usr) { return usr; } //(A) int main() { User u("Xino", 120); User y = f(u); //(B) cout << y.name << endl; // Xino return 0; }




Programming With Objects[c] A Comparative Presentation of Object-Oriented Programming With C++ and Java
Programming with Objects: A Comparative Presentation of Object Oriented Programming with C++ and Java
ISBN: 0471268526
EAN: 2147483647
Year: 2005
Pages: 273
Authors: Avinash Kak

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net