简体   繁体   中英

‘base’ is an inaccessible base of ‘deriv’

Why is base inaccessible to deriv inside deriv ? The program compiles with class deriv : public base .

#include <cstdio>

class base
{
};

class deriv : base
{
  public:
  void f(deriv, int){printf("deriv::f(deriv, int)\n");}
  void f(base){printf("deriv::f(base)\n");}
};

int main()
{
  deriv d;
  d.f(d);
}

17: error: ‘base’ is an inaccessible base of ‘deriv’
17: error:   initializing argument 1 of ‘void deriv::f(base)’

Because two people got it wrong already, I will ask in bold: why does base need to be publicly inherited ? It is accessed from within deriv only.

If you define a class with the class keyword, then members and base classes are private by default.

If the base class needs to be public, then either explicitly declare it public (as you mention in the question), or use the struct keyword which makes things public by default.

why does base need to be public?

In this case, your call to f(base) requires a conversion from deriv to base , and such a conversion is only possible if the base class is accessible. Being private, it is not accessible in main , which is where the conversion is required.

You seem to be incorrectly assuming that conversion from deriv to base when calling deriv::f(base) occurs "inside deriv " and thus has to be accessible. This is not the case. When you call a function, all conversions necessary for initializing function's arguments occur in the caller's context. They are not "inside derive ". They happen in the "outside world". And in your case the "outside world" has no access to deriv -to- base conversion.

In your specific case it is main that is trying to convert deriv to base . And main cannot do it since it has no access to the private base of deriv . Just to experiment you can declare int main() as a friend of deriv and the code will compile.

Because it is privately inherited :

class deriv : base

The default inheritance for class is private, meaning other classes and functions do not have access to the base class of the derived class.


There is a small problem in your example. This :

  deriv d;
  d.f(d);

is not going to do what you expect it to do because of slicing.

If we fix the above problem by changing the signature of the f to this :

void f(base&){printf("deriv::f(base)\n");}

there is still a problem accessing the base class of deriv , because it inherited privately from the base.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM