Home > Net >  Base class constructor automatic call
Base class constructor automatic call

Time:02-16

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;
}

same output::

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:

  1. It calls the default constructor B() of class B.
  2. Then the default constructor A() of class A is implicitly called. This sets the non-static data member x of the subobject to 5.
  3. Finally, the body of the default constructor 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.

Case 2

Here we consider the statement:

B b2(2008);

The above statement has the following effect:

  1. The parameterized ctor B(int) of class B is called.
  2. Then the default ctor A() of class A is implicitly called. This sets the non-static data member x of the subobject to 5.
  3. Finally, the body of the parameterized ctor 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.

Case 3

Here we consider the statement:

B b3("Random string");

The above statement has following effects:

  1. The parameterized ctor B(std::string) of class B is called.
  2. Then the default ctor A of class A is implicitly called. This sets the non-static data member x of the subobject to 5.
  3. Finally, the body of the parameterized ctor 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.

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.

  •  Tags:  
  • c
  • Related