I have troubles understanding the output of the following code when it comes to the first printed number.
#include <iostream>
#include <string>
using namespace std;
class A{
public:
int x;
A(){
x = 5;
}
};
class B: public A{
public:
static int x;
B(){
x ;
}
B(int i){
x = x i;
}
B(string s){
x--;
}
};
int B::x=10;
int main()
{
B b1;
B b2(2008);
B b3("Random string");
cout << b1.x << " : " << b2.x << " : " << b3.x << endl;
return 0;
}
output (the first "2018" is the one I'm having troubles with)
2018 : 2018 : 2018
CodePudding user response:
The first thing to note is that A::x is different from B::x. B does inherit A::x, but it introduces a new B::x which is static. Hence x in the scope of Brefers to B::x (not to A::x). Ergo, you can remove the base class without changing the output:
#include <iostream>
#include <string>
using namespace std;
class B {
public:
static int x;
B(){
x ;
}
B(int i){
x = x i;
}
B(string s){
x--;
}
};
int B::x=10;
int main()
{
B b1;
B b2(2008);
B b3("Random string");
cout << b1.x << " : " << b2.x << " : " << b3.x << endl;
}
2018 : 2018 : 2018
Now, B::x starts out as 10 because thats what you initialize it to. Then B b1; increments it (in the default constructor), then B b2(2008); adds 2008 to B::x, it is 2019 now. Eventually B b3("Random string"); decrements it to arrive at the value 2018. Because B::x is static you see 3 times the same output.
The confusion seems to be caused by B::x being a static member and A::x being hidden by B::x. To reiterate the above: static int x; declares x to be a static member. There is only 1 for all instances. When one instance increments it then any other instance will see the incremented value as well. B::x hides A::x because they have the same name. I suppose this is not intentional. If your intention was to let B inherit x from B and use that, then you should remvoe the delcaration and definition of B::x.
It's not that I don't understand a static variable, it's more like me not getting why b1 that (seemingly) call b(),outputs 2018 instead of incrementing the static x to 11
The line B b1; does increment A::x from 10 to 11. Though the constructor does not produce any output. The values are only printed after all constructors finished.
CodePudding user response:
Your static data member x inside the derived class B hides the nonstatic data member x from base class A since they both have the same name. The explanation of the output is given below.
Case 1
Here we consider the statement:
B b1;
The above statement has the following effects:
- It calls the default constructor
B()of classB. - Then the default constructor
A()of class A is implicitly called. This sets the non-static data memberxof the subobject to5. - Finally, the body of the default constructor
B()is executed. Due to thisx ;is evaluated and soxnow is11. This is because the non-static data memberxfrom base classAis hidden by the static data memberxof derived classB. Sox ;increments the static data member(which was10) instead of the nonstatic data member from baseA.
Case 2
Here we consider the statement:
B b2(2008);
The above statement has the following effect:
- The parameterized ctor
B(int)of classBis called. - Then the default ctor
A()of classAis implicitly called. This sets the non-static data memberxof the subobject to5. - Finally, the body of the parameterized ctor
B(int)is executed. Due to thisx = x i;is evaluated and so the static data memberxbecomes2019(since x was11andiis2010). This is because the non-static data memberxfrom base classAis hidden by the static data memberxof derived classB. Sox = x i;uses the static data member(which was11) instead of the non-static data member from baseA.
Case 3
Here we consider the statement:
B b3("Random string");
The above statement has following effects:
- The parameterized ctor
B(std::string)of classBis called. - Then the default ctor
Aof classAis implicitly called. This sets the non-static data memberxof the subobject to5. - Finally, the body of the parameterized ctor
B(std::string)is executed. Due to thisx--;is evaluated and so nowxcontains2018. This is because the non-static data memberxfrom base classAis hidden by the static data memberxof derived classB. Sox--;decrements the static data member(which was2019) instead of the non-static data member from baseA.
So now the static data member x has the value 2018.
Case 4
Here we consider the statement:
cout << b1.x << " : " << b2.x << " : " << b3.x << endl;
The above statement uses the static data member x values because the non-static data member x is hidden. And since the static data member x has the value 2018 you get the output you mentioned.
