Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

Returned value(s)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 lucky6969b   Members   -  Reputation: 359

Like
0Likes
Like

Posted 07 September 2012 - 10:35 PM

What are the benefits of each method?
Method A:
Object& GetStuff()
{
	  return obj;
}

Method B:
void GetStuff(Object& obj)
{
	   obj = otherobj;
}
When should I use each of them?
Thanks
Jack

Sponsor:

#2 Aressera   Members   -  Reputation: 898

Like
0Likes
Like

Posted 07 September 2012 - 11:13 PM

Method A:
  • Doesn't copy obj, just returns a reference to it.
  • Allows the caller to modify the value of obj if they want.
Method B:
  • Copies the value of obj into the reference parameter.
  • Requires the caller to already have an Object value somewhere.
  • The caller can't modify the value of obj directly.
  • Allows the caller to pass information into the function which might be useful in some cases.
To be honest, I don't use Method A ever, mainly because it allows the caller to modify the value. I prefer to return a const reference instead. Method B isn't really worth it here because of the copy overhead, but that pattern can be useful if you have a function that takes an existing Object and does some modification to it.

In general, use const liberally wherever it makes sense and your code will be more robust.

#3 Bregma   Members   -  Reputation: 2777

Like
0Likes
Like

Posted 08 September 2012 - 06:47 AM

Computers are calculating machines, and programming is an act of mathematics (some who have not studied the theory insist that statement is not true). One of the fundamental concepts used frequently in mathematics is that of the function: a relation from one domain onto another. You will notice in fact in C-based languages subroutines are often referred to as functions. A true function in C takes zero or more arguments, does not modify them, has no side effects, and returns a value (thus relating the domain of the argument tuple to the function result). You will see this form of subroutine call very frequently, because the robust mathematical underpinnings allow the programmer to reason more easily about the program.

Some times a function is inappropriate, and some other relation is manifest through a subroutine call. These include subroutines with side effects or which return tuples that are not wrapped in a data structure. These are more appropriately patterened without return values.

If you are using your data in an overtly mathematical manner, you need to use the function syntax. For example, you might be creating a vector library and want to allow for the addition of two vectors.
  class vector { ... };

  vector operator+(vector const& lhs, vector const& rhs)
  {
	...
  }

  int main()
  {
	vector a(1, 1), b(2, 2), c(3, 3);
	vector d = a + b + c;
  }
See how returning the value from the function allows the functions to be chained using a trditional algebraic syntax?
Stephen M. Webb
Professional Free Software Developer

#4 BinaryPhysics   Members   -  Reputation: 287

Like
0Likes
Like

Posted 08 September 2012 - 08:48 AM

Assuming that 'obj' is local to the function 'A' it's going to return garbage. Never return pointers or references to local objects because they're destroyed when execution leaves the scope of the function.

However, if its a member function the returning a reference to '*this' is useful for chaining as seen when passing to 'cout' and in Bregma's example.

Edited by BinaryPhysics, 08 September 2012 - 08:49 AM.


#5 Bacterius   Crossbones+   -  Reputation: 3591

Like
0Likes
Like

Posted 08 September 2012 - 09:23 AM

From my point of view (and assuming scope rules are observed), the first one is used when you conceptually want the method to give you something (e.g. getUserData(userID)), and the second one is better when you want the method to act on what you give it instead, such as populateUserList(&myList). You can also think of it in terms of ownership - the first method logically owns the object it returns, whereas in the second method, the caller of the method owns the object, which can make a difference depending on your design.

"The best comment is a deleted comment."
website · blog

[maintenance in progress]


#6 Servant of the Lord   Marketplace Seller   -  Reputation: 8961

Like
0Likes
Like

Posted 09 September 2012 - 12:18 PM

Depending on the usage, and on whether you are using move-semantics, here are the benefits of the three versions:

Return a reference: (requires that the lifetime of the return persists longer than the function call)
Object& GetStuff()
Lets you operate on the returned variable.

myClass.GetStuff() = 50;
myClass.GetStuff().x();

It's also useful for chaining operators if you return (*this) by reference. std::cout takes advantage of this, for example.
Object &operator<<(parameter)
{
	 //use the parameter here.

	 return *this;
}

Object myObject;
myObject << parameter << parameter << parameter;
(((myObject << parameter) << parameter) << parameter);

Take a reference as a parameter:
int GetStuff(Object& obj)

Useful for function calls where you want to return multiple variables from one call.
int x, y;
void FillXY(x, y);

Example usage in the standard library:
std::ifstream file("file.txt");

int maxChars = 50;
char *buffer = new char[maxChars];

int actualNumberOfCharsRead [out] = file.readsome(buffer [in and out], maxChars [in]);

Return a value:
Object GetStuff();

Useful when GetStuff() no longer needs Object, because with C++11 move-semantics, no copy is actually made if the compiler detects that the returned value is about to be destructed.

Example:
std::vector<std::string> GetStuff(std::vector<std::string> passByValue) {return passByValue;}

std::vector<std::string> veryLargeVector;
veryLargeVector.resize(2000, "very large string containing alot of data"); //2000 copies of the string "very large string containing alot of data".

std::vector<std::string> notACopy = GetStuff(veryLargeVector); //No copy made - not in passing the variable in, and not in return the variable.

The key to it not being copied is that 'veryLargeVector' is never used after being passed into GetStuff(), so move semantics let's GetStuff's parameter (in this call) actually _be_ veryLargeVector, instead of copying it.
[Edit:] I was mistaken here. See this thread for more info.

Then, since GetStuff's variable 'passByValue' isn't used after being returned, move semantics (again) lets notACopy _be_ passByValue (which _was_ veryLargeVector) without copying it.

 

By default, with modern C++ (C++11 standard):

Returning from functions:
- Return by value unless...
- It the variable lasts beyond the function call (like member variables), in which case you return by const reference unless...
- You want the result to actually modify the original variable, in which case you return a non-const reference.

Passing parameters:
- Pass by const reference unless...
- It's a small variable that'll fit in a CPU register (float, int, etc...), in which case you pass by value or...
- You want the variable passed in to come back out with new values, in which case you pass by non-const reference.

This changes if you're talking about dynamic memory, in which case you return/pass pointers... but in modern C++, your dynamic memory should actually be handled by smart pointers (>95% of the time), and so all the above applies to returning the smart pointer instead of the memory the smart pointer points at.

Edited by Servant of the Lord, 01 November 2012 - 09:22 PM.

All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.

Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS