为什么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
内访问。
答案 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
时仍然存在问题,因为它是从基类私下继承的。