我有一个继承问题: 假设我已经
了class Time{
protected:
void foo();
};
以及
class Base: private Time{
void foo1(){ foo(); }
};
class Child: public Base, private Time{
void foo2(){ foo(); }// here my compiler says that foo is ambiguous
};
为什么foo()不明确,如果Time in Base的继承是私有的?
PS。 只是为了那些需要查看完整代码的人,这里是GitHub项目: https://github.com/huntekah/Interior_decorator-OpenGL_Project/blob/master/Grafika-OpenGL/Interior_decorator/Display.cpp#L133 class Time(utilities目录)由ControlObjects和ControlCamera继承,它们都是Controls的基础。显示继承控件,另外还有时间。注释行显示SetDeltaTime()不明确的地方;
答案 0 :(得分:1)
你的代码中还有另一个错误:类库从类Time继承私有,类Child从类时间私下再次继承!!!
继承法:
COLUMN A
info|info2|info3
Base有一个Time类的副本,因为它继承了它。
child有一个Base类的副本,因为它继承了它。
*** Child有一个Time类副本,因为它的父母(Base)有这个副本。
如果Child尝试从类中显式继承,则Time将发出编译时错误:错误C2584:' Child' :直接基地'时间'无法进入;已经是' Base'
的基础答案 1 :(得分:0)
初步评论
由于其他原因,您的代码段无法编译:{{1}}无法访问Base
Time
,因为它是私人会员。因此foo()
会导致错误,然后才能报告歧义。
如果您更改foo1()
以使其成员受到保护,那么您可以完全按照您的描述重现错误:
Time
这里有什么问题?
class Time{
protected:
void foo();
};
私下继承Base
,因此预计其外部世界不会看到它的成员。
但对于外部世界而言,对于派生类来说,情况并非如此。在派生的情况下,名称查找规则说首先在类层次结构中查找名称,然后应用重载,而不仅仅是执行访问控制:
10.2 / 1 成员名称查找确定类范围中名称( id-expression )的含义。名称查找可以导致 模棱两可,在这种情况下,程序是不正确的。为 id-expression ,名称查找从此类的范围开始;对于qualified-id,名称查找开始于 嵌套名称符。名称查找在访问之前发生 控制。强>
10.2 / 8 如果明确找到重载函数的名称,则在访问控制之前也会发生重载分辨率。 通常可以通过使用其类来限定名称来解决歧义 名。
使用多重继承时:
Time
所以你继承了Time
:
:
Base Time
\ :
\ :
Child
两次,一次是通过私人继承而是通过公共。这种歧义使得foo()
中的foo
名称根据标准不明确,并且在验证访问权限之前,使您的代码无效。
请注意,Child看到2 foo()但具有讽刺意味的是不能使用它们:两者都来自私有继承。因此,即使您解决了歧义,您也会收到有关辅助功能的其他错误消息。