3

为什么base无法进入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只能从内部访问。

4

3 回答 3

6

如果使用class关键字定义类,则成员和基类默认为私有。

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

为什么 base 需要公开?

在这种情况下,您的 to 调用f(base)需要从derivto转换base,并且只有在基类可访问的情况下才能进行这种转换。由于是私有的,它在 中是不可访问的main,这是需要转换的地方。

于 2012-12-20T08:10:00.250 回答
6

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

在您的特定情况下,它main正在尝试转换derivbase. 并且main不能这样做,因为它无法访问deriv. 只是为了试验,您可以声明int main()为的朋友,deriv代码将编译。

于 2012-12-20T08:23:08.890 回答
3

因为它是私人继承的:

class deriv : base

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


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

  deriv d;
  d.f(d);

由于切片,不会做你期望它做的事情。

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

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

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

于 2012-12-20T08:10:01.887 回答