'base'是'衍生'的难以接近的基础

时间:2012-12-20 08:09:02

标签: c++ inheritance

为什么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内访问。

3 个答案:

答案 0 :(得分:6)

如果使用class关键字定义类,则默认情况下成员和基类是私有的。

如果基类需要公开,那么要么显式声明它public(正如你在问题中提到的那样),要么使用struct关键字,默认情况下会公开。

  

为什么基地需要公开?

在这种情况下,您对f(base)的调用需要从deriv转换为base,并且只有在可以访问基类时才能进行此类转换。由于是私有的,main无法访问,这是转换所需的位置。

答案 1 :(得分:6)

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

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

答案 2 :(得分:3)

因为它是私人继承的:

class deriv : base

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


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

  deriv d;
  d.f(d);
由于切片,

不会按预期执行。

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

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

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