[英]Multiple inheritance with no function overriding. Why the ambiguity
Here are my classes. 这是我的课。 This is just
这只是
#include<iostream>
using namespace std;
class Base
{
public:
int var;
Base(int val) : var(val)
{}
void foo()
{
cout << "Class Base foo()" << endl;
}
};
class Derived_A : public Base
{
public:
Derived_A(int val) : Base(val)
{}
};
class Derived_B : public Base
{
public:
Derived_B(int val) : Base(val)
{}
};
class Derived_AB : public Derived_A, public Derived_B
{
public:
Derived_AB(int var1, int var2) : Derived_A(var1), Derived_B(var2)
{}
};
int main(int argc, char** argv)
{
Derived_AB ABDerObj(1,2);
ABDerObj.foo();
return 0;
}
And this gives me a compiler error saying the foo call is ambiguous. 这给了我一个编译器错误,说foo调用是模棱两可的。
Function foo is not overridden anywhere. 函数foo在任何地方都不会被覆盖。 I understand there are two instances of class Base because there is no virtual inheritance.
我了解有Base类的两个实例,因为没有虚拟继承。 So there are two 'var' variables.
因此,有两个“ var”变量。 But I don't understand why the compiler is having ambiguity in foo call.
但是我不明白为什么编译器在foo调用中有歧义。 Functions are not instance specific.
函数不是特定于实例的。 They are class specific.
它们是特定于类的。 Why is the compiler giving an error?
为什么编译器给出错误?
I am using Visual Studio 2013. 我正在使用Visual Studio 2013。
Thank you. 谢谢。
The multiple inheritance makes you inherit two times the function foo(): one as part of Derived_A
and one as part of Derived_B
, because each of it inherits its own BaseClass
. 多重继承使您可以继承函数foo()的
Derived_A
:一次是Derived_A
一部分,一次是Derived_B
一部分,因为每个继承自自己的BaseClass
。
BaseClass BaseClass
| |
Derived_A Derived_A
\ /
\ /
Derived_AB
So the compiler doesn't know if it shall execute it with the data of the Derived_A
or Derived_B
subobject. 因此,编译器不知道是否应使用
Derived_A
或Derived_B
子对象的数据执行它。
Solutions: 解决方案:
1) You can disambiguate explicitely in every call you make: 1)您可以在每次通话中明确消除歧义:
ABDerObj.Derived_A::foo(); // execute foo() for the Deived_A object
2) You can disambiguate explicitely at the class level, by defining a common foo, for example: 2)您可以通过定义公共foo在类级别上明确消除歧义,例如:
void foo()
{
Derived_A::foo(); // you want all the foos called
Derived_B::foo();
}
3) If you want to have only a single BaseClass
for your Derived_AB
, then you should make BaseClass a virtual base class for Derived_A
and Derived_B
. 3)如果您只希望
Derived_AB
具有单个BaseClass
,则应使BaseClass成为Derived_A
和Derived_B
的虚拟基类。 Then Derived_AB
will have only one single BaseClass
and the call to foo()
is no longer ambiguous. 然后
Derived_AB
将只有一个BaseClass
并且对foo()
的调用不再是模棱两可的。
BaseClass
/ \
/ \
Derived_A Derived_A
\ /
\ /
Derived_AB
(PS in this case, you shall also define a BaseClass()
initializer for Dervived_AB.
) (在这种情况下,PS还将为
Dervived_AB.
定义一个BaseClass()
初始化Dervived_AB.
)
Functions are not instance specific.
函数不是特定于实例的。 They are class specific.
它们是特定于类的。
That is only true for static functions. 这仅适用于静态函数。 Suppose I change your implementation of
foo()
to the following: 假设我将
foo()
实现更改为以下内容:
void foo()
{
cout << "My value is " << var << endl;
}
What do you expect ABDerObj.foo();
您期望
ABDerObj.foo();
to print? 打印?
Since this is an answer, let me also provide two possible solutions. 因为这是一个答案,所以让我也提供两种可能的解决方案。
If foo
really is instance-specific (for example, because it uses the class field var
, you can easily tell the compiler which Base::foo()
you want to call (the Derived_A
or the Derived_B
version) by specifying which one you want to use 如果
foo
确实是特定于实例的(例如,因为它使用类字段var
,则可以通过指定所需的哪个)来轻松告诉编译器您要调用哪个Base::foo()
( Derived_A
或Derived_B
版本)使用
ABDerObj.Derived_A.foo(); // prints: My value is 1
ABDerObj.Derived_B.foo(); // prints: My value is 2
or by just throwing away the other part: 或只丢掉另一部分:
((Derived_A) ABDerObj).foo(); // prints: My value is 1
((Derived_B) ABDerObj).foo(); // prints: My value is 2
The latter is mostly useful if you have a block of code where you are going to use only the Derived_A
functionality, for example: 如果您有一个代码块仅使用
Derived_A
功能,则Derived_A
有用,例如:
Derived_A& ABDerObjPartA = ABDerObj;
ABDerObjPartA.foo();
// more code using ABDerObjPartA.
On the other hand, if -- to stick with your terminology -- the definition of foo
really depends on the class and not on the instance, make it static
: 在另一方面,如果-坚持使用您的术语-的定义
foo
真的取决于类,而不是实例,使之static
:
// In Base:
static void foo()
{
cout << "Class Base foo()" << endl;
}
// in main():
ABDerObj.foo(); // This is now OK
What you should really be looking into is whether you actually need multiple inheritance, especially with the same base class occurring more than once. 您真正应该研究的是您是否确实需要多重继承,尤其是同一基类多次出现。 Often once you start having these disambiguation problems they keep getting worse and a slight redesign of your code will make it much more maintainable.
通常,一旦开始出现这些歧义性问题,它们就会变得越来越糟,对代码进行稍微的重新设计将使其更加易于维护。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.