“基础”是“派生”的无法访问的基础

‘base’ is an inaccessible base of ‘deriv’

本文关键字:访问 派生 基础      更新时间:2023-10-16

为什么deriv中的deriv无法访问?该程序用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)’

由于两个人已经错了,所以我会粗体问:为什么base需要公开继承?它仅在deriv内访问。

您似乎错误地假设从deriv转换为base时,调用deriv::f(base)发生在" deriv"内部,因此必须可以访问。不是这种情况。当您调用函数时,初始化函数参数所需的所有转换都会发生在呼叫者的上下文中。它们不是"内部derive"。它们发生在"外界"中。在您的情况下,"外界"无法访问deriv -TO- base转换。

在您的特定情况下,是main试图将deriv转换为basemain无法执行此操作,因为它无法访问deriv的私有基础。只是为了实验,您可以将int main()声明为deriv的朋友,并且代码将编译。

如果使用class关键字定义类,则成员和基类是私人的。

如果基类需要公开,则可以明确声明其public(如您在问题中提到),或使用struct关键字,该关键字默认情况下使事物公开。

为什么基本需要公开?

在这种情况下,您对f(base)的呼叫需要从deriv转换为base,并且只有在可以访问基类的情况下,这种转换才有可能。是私人的,在main中无法访问,这是需要转换的地方。

,因为它是私下继承的:

class deriv : base

class的默认继承是私有的,这意味着其他类和功能无法访问派生类的基类。


您的示例中存在一个小问题。这个:

  deriv d;
  d.f(d);

由于切片而不会做您期望的事情。

如果我们通过更改f的签名来解决上述问题:

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

访问deriv的基类仍存在问题,因为它是从基地私下继承的。