C ++ - Why does default constructor work even in private inheritance

The next question made this phenomenon notice where the constructor is being called even in private inheritance mode.

I tried this on Diamond Problem and then made it easy to break the diamond rule and just keep virtual inheritance .

Then I made a simple example of 3-level inheritance which I show below ( C

, inherited B

and B

inherited C

- as in private inheritance ) and the constructor is still called A

.

It should not A()

be private

and not available in C

?

#include<iostream>
using namespace std;
class A
{
public:
     A(){ cout << "1"; }
};

class B:  A
{
public:
    B(){ cout << "2"; }
};

class C:  B
{
public:
   C(){ cout << "3"; }
};


int main()
{
   C c1;
}

      

Output: 123

(You can also view the code and output here )

PS : I've tried this with both the normal case (here) and inheritance virtual

, even with the "Diamond-Problem" - the answer is the same every time.

+3


source to share


1 answer


There is no virtual inheritance, so it is not up to C to build A. Therefore, the constructor for C calls the constructor for B, which in turn calls the constructor for A. There is no alleged violation of access specifiers.

In the case of virtual inheritance, note that the construction of subelements omitted from the member initialization list is determined by

[class.base.init / 9]

In a non-delegated constructor, if a given potentially constructed subobject is not denoted by a mem-initializer identifier (including the case where there is no mem-initializer list, since the constructor does not have a ctor initializer), then

  • ...
  • ...
  • otherwise, the object is initialized by default.

So the above sentence seems to indicate that default initialization should happen and, as it is argued, access specifiers can be dropped.

It is important to remember that access specifiers restrict which programs can be referenced within a class definition; they will not stop the compiler from emitting the correct code, such as the one required by the above proposal.



If, however, you tried to explicitly call the default constructor for the virtual base, it will be ill-formed, like this :

#include<iostream>
using namespace std;
class A
{
public:
     A(){ cout <<"1";}
};

class B:  virtual A
{
public:
    B(){cout <<"2";}
};

class C:  B
{
public:
   C() : A() {cout<<"3";}
};

int main()
{
   C c1;
}

      

What gives:

prog.cpp: In constructor ‘C::C()’:
prog.cpp:18:10: error: ‘class A A::A’ is inaccessible within this context
    C() : A() {cout<<"3";}
          ^
prog.cpp:4:1: note: declared here
 {
 ^

      

Why? Because now your program is trying to explicitly violate the access, not the compiler doing its job.

+2


source







All Articles