In the previous lessons, if we wanted a variable that could be updated from any function, we've stored that as a global variable.
This is because, based on what we've learned so far, a function cannot update a variable that is stored in another function.
To illustrate the issue we have, lets try this:
#include <iostream>
using namespace std;
class Character {
public:
int Health { 150 };
}
void Combat(Character Monster) {
Monster.Health -= 50;
}
int Main() {
Character Monster;
Combat(Monster);
cout << Monster.Health;
}
Perhaps surprisingly, what this program logs out is 150
rather than the 100
we might expect.
We can simplify the problem even further:
#include <iostream>
using namespace std;
void Increment(int Number) {
Number++;
}
int Main() {
int Number { 1 };
Increment(Number);
cout << Number;
}
For similar reasons, this code will log out 1
, not 2
. It is perhaps more intuitive in this case why our code doesn't seem to be incrementing Number
, especially given our earlier lesson on scopes.
The problem is that the Number
inside our Increment
function is not the same variable as the Number
inside the main
function. It is a copy of the variable that, at least initially, has the same value.
After running the following code, what is the value of x
?
void Increment(int Number) {
return Number + 1;
}
int x { Increment(1) };
After running the following code, what is the value of x
?
void Increment(int Number) {
Number++;
}
int x { 1 };
Increment(x);
This behavior of how arguments are passed to functions is called pass-by-value. This means the arguments we pass in to functions have their value copied to a new variable. So, each variable has its own memory location. They have the same value at first, but are then updated independently By default, C++ passes arguments in this way.
So, we might now better understand what was happening with our more complex Monster
object in the previous example. Specifically when we are passing our object to the Combat
function:
Character Monster;
Combat(Monster);
The effect of the above code was that our monster object was copied when it was sent to the Combat
function.
Anything that happened to our monster in the Combat
function was happening to the copy. The monster in the main
function was a different object.
Therefore, the health of the monster in our main
function was still 150 - it was the health of the copy that was being reduced within the Combat
function.
That copy effectively disappears when our Combat
function completes.
Fortunately, pass-by-value is not the only option we have. The alternative method is pass-by-reference, and we will see how to do that in the next lesson!
Become a software engineer with C++. Starting from the basics, we guide you step by step along the way