0

After some years without touching c++, I am getting back at it and decided to study again using a text book ("Sutherland, Bruce. Learn C++ for Game Development (p. 59). Apress. Kindle Edition."). I have 2 quick questions:

1) In one example, the book uses the following lines of code to call a function:

string playerInput; 
GetPlayerInput( playerInput);

And the function itself is defined as:

void GetPlayerInput(string& playerInput) 
{ 
    cin >> playerInput; 
} 

Question: The "playerInput" being passed as "string&". Is it really necessary? Why is this being passed as reference when we could just make the function return a string and do it like this:

string playerInput; 
playerInput = GetPlayerInput();

And:

string GetPlayerInput() 
{ 
    cin >> playerInput; 
    return playerInput;
}

Is this just a stylistic choice or I am missing something here?

2) An class accessor method to get a user name was defined as:

'void SetName(const std::string& name);'

No other explanation. What's up with this "const" thing? I did some research but only got more confused. Why would you need it when passing a string as a parameter (and again as reference??)

Thank you so much for any help!

sorush-r
  • 10,490
  • 17
  • 89
  • 173
mbr_uk
  • 33
  • 7
  • Here is a nice list of [C++ books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). Very well explained in Scott Meyers books. –  Jan 04 '17 at 10:54
  • have a look at the concept of pass by value and pass by reference. If you pass by value then you are needlessly calling the copy constructor (depends upon the requirement), and const because you may not want to accidentally write it when you should not. And as per one suggestion, please go through Scott Meyers book – D Untouchable Jan 04 '17 at 10:56
  • thanks. Book is now on my "to read" list next :-) – mbr_uk Jan 04 '17 at 12:52

2 Answers2

1

1) In principle, returning by value involves a copy. Nevertheless, virtually all compilers perform RVO/NRVO even in the debug mode.

So in general it is an API choice, however it can be significant if used in the loop. Compare the two, for example:

for (;;) {
    string playerInput = GetPlayerInput();
    if (playerInput.empty()) break;
    // do something with the playerInput
}

string playerInput;
for (;;) {
    GetPlayerInput(playerInput);
    if (playerInput.empty()) break;
    // do something with the playerInput
}

There is a subtle difference, which makes the later case much more performant. In the first case, even with NRVO, the string is newly allocated each time. In the second case, on the contrary, the string is only allocated/reallocated a few times and at the end it has the size of the longest input.

Also, the GetPlayerInput could then return bool, which would make the loop much better looking:

string playerInput;
while (GetPlayerInput(playerInput)) {
    // do something with the playerInput
}

2) Passing by const ref (as opposed to non-const ref) not only makes it impossible to modify the parameter by mistake, but also makes it possible to use temporaries, which is arguably even more important. As an example:

setName("Some name");

does not work with non-const reference.

When passing by value, there is again a copy involved - it might be elided (it is allowed in C++, which has the downside that code relying on copying might not work), but it is not guaranteed (and only works when passing temporaries btw.).

The only case where it is advisable to use pass by value is when you would copy the parameter internally anyway, like for example:

SomeClass operator +(SomeClass a, const SomeClass& b) {
    return a += b;
}

contrary to

SomeClass operator +(const SomeClass& a, const SomeClass& b) {
    SomeClass result = a;
    return result += b;
}
EmDroid
  • 5,918
  • 18
  • 18
  • The more important part of #2 what you forgot is that passing by `std::string` instead of `const std::string&` might copy, once again, this is just for optimization. – Hatted Rooster Jan 04 '17 at 11:09
  • That's right, however I was comparing passing by "`std::string&`" vs "`const std::string&`". But it is true that the OP also questions the reference. – EmDroid Jan 04 '17 at 11:12
  • Thanks all for the answers/comments. I might be jumping too much ahead asking these kinds of questions (maybe they'd be naturally answered as I continued to study and practive) but this makes much more sense now! Again, sorry about the newbie questions but really appreciate the help. – mbr_uk Jan 04 '17 at 13:17
0

It totally depends on the programmer whether to pass by reference or by value. If you're talking about passing by reference, the changes will be made in the original value of the variable whereas, if you use passing by value a copy of actual arguments is passed to formal arguments of the called function. So, you can do both!

Dreamer
  • 112
  • 1
  • 14