
Keith B. answered 08/22/19
Software Engineer and Math Geek
Your code example is a little incomplete, the class Foo has no bar to set, so I'm going to make an assumption:
class Foo
{
public:
Foo(int num) : bar(num) {}
private:
int bar;
};
As for your question, you need to know a little about how variables are stored in memory, what their initial value is, and the underlining machine code that gets written when the code gets compiled. When you declare a variable, memory is set aside on the machine for that variable to store it's value. When you say,
int bar;
space is set aside to store a integer; it's initial value is said to be undefined -- it's whatever value is in that memory location if it was previously used (A frequent error in large coding projects is uninitialized variables). (BTW, this is for release mode -- debug mode tends to zero out memory for you). A good practice is to do:
int bar = 0;
When you start dealing with classes, member elements can be initialized within the constructor, so that when the class is instantiated (ie, brought into existance) it is ready to go. In the example class, our constructor (or CTOR) could have been written as:
Foo(int num)
{
bar = num;
}
And that would have been perfectly acceptable. The question to ask then, what would be the output of this:
Foo(int num)
{
cout << "bar=" << bar << endl;
bar = num;
}
The unanswer is: undefined. bar has no value, as while space was assigned to hold its value, there's no telling what was in that space prior to it's assignment. Additionally, extra code is generated at the machine level, first to declare it then assign a value to it. The use of the colon (:) operator provides a means to initialize member variables within a class.
Foo(int num) : bar(num)
{
cout << "bar=" << bar << endl;
}
initializes the value of bar at declaration, removing the extra step. Note: most modern compilers can optimize this out, meaning they can see that a variable is not being used between creation and the first assignment, and they'll reduce the extra code down, but it's better to not count on that for more efficient code.
Lastly, when you get into inheritance, where one class is defined as an "offspring" of another, the colon operator is used to pass values "up" to the base parent class.