Reputation: 37
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
Upvotes: 0
Views: 56
Reputation: 1
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.
Here we consider the statement:
B b1;
The above statement has the following effects:
B()
of class B
.A()
of class A is implicitly called. This sets the non-static data member x
of the subobject to 5
.B()
is executed. Due to this x++;
is evaluated and so x
now is 11
. This is because the non-static data member x
from base class A
is hidden by the static data member x
of derived class B
. So x++;
increments the static data member(which was 10
) instead of the nonstatic data member from base A
.Here we consider the statement:
B b2(2008);
The above statement has the following effect:
B(int)
of class B
is called.A()
of class A
is implicitly called. This sets the non-static data member x
of the subobject to 5
.B(int)
is executed. Due to this x = x + i;
is evaluated and so the static data member x
becomes 2019
(since x was 11
and i
is 2010
). This is because the non-static data member x
from base class A
is hidden by the static data member x
of derived class B
. So x = x+i;
uses the static data member(which was 11
) instead of the non-static data member from base A
.Here we consider the statement:
B b3("Random string");
The above statement has following effects:
B(std::string)
of class B
is called.A
of class A
is implicitly called. This sets the non-static data member x
of the subobject to 5
.B(std::string)
is executed. Due to this x--;
is evaluated and so now x
contains 2018
. This is because the non-static data member x
from base class A
is hidden by the static data member x
of derived class B
. So x--;
decrements the static data member(which was 2019
) instead of the non-static data member from base A
.So now the static data member x
has the value 2018
.
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.
Upvotes: 1
Reputation: 122478
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 B
refers 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.
Upvotes: 3