没有函数重写的多重继承.为什么模棱两可
Multiple inheritance with no function overriding. Why the ambiguity
这是我的类。这只是
#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;
}
这给了我一个编译器错误,说foo调用不明确。
函数foo不会在任何地方被重写。我知道基类有两个实例,因为没有虚拟继承。所以有两个变量。但我不明白为什么编译器在foo调用中有歧义。函数不是特定于实例的。它们是特定类别的。为什么编译器会出错?
我正在使用Visual Studio 2013。
谢谢。
多重继承使您继承两次函数foo():一次作为Derived_A
的一部分,另一次作为Derived_B
的一部分。因为每个函数都继承了自己的BaseClass
。
BaseClass BaseClass
| |
Derived_A Derived_A
/
/
Derived_AB
所以编译器不知道是用Derived_A
还是Derived_B
子对象的数据来执行它。
解决方案:
1) 你可以在每次打电话时明确地消除歧义:
ABDerObj.Derived_A::foo(); // execute foo() for the Deived_A object
2) 您可以在类级别通过定义一个常见的foo来明确地消除歧义,例如:
void foo()
{
Derived_A::foo(); // you want all the foos called
Derived_B::foo();
}
3) 如果您希望Derived_AB
只有一个BaseClass
,那么您应该使BaseClass成为Derived_A
和Derived_B
的虚拟基类。则CCD_ 10将仅具有一个单独的CCD_。
BaseClass
/
/
Derived_A Derived_A
/
/
Derived_AB
(注意,在这种情况下,您还应该为Dervived_AB.
定义一个BaseClass()
初始值设定项)
函数不是特定于实例的。它们是特定类别的。
这只适用于静态函数。假设我将foo()
的实现更改为以下内容:
void foo()
{
cout << "My value is " << var << endl;
}
您希望ABDerObj.foo();
打印什么?
既然这是一个答案,让我也提供两种可能的解决方案。
如果foo
确实是特定于实例的(例如,因为它使用类字段var
,您可以通过指定要使用的Base::foo()
来很容易地告诉编译器要调用哪个CCD_19(Derived_A
或Derived_B
版本)
ABDerObj.Derived_A.foo(); // prints: My value is 1
ABDerObj.Derived_B.foo(); // prints: My value is 2
或者只是扔掉另一部分:
((Derived_A) ABDerObj).foo(); // prints: My value is 1
((Derived_B) ABDerObj).foo(); // prints: My value is 2
如果您有一个代码块,其中只使用Derived_A
功能,则后者最有用,例如:
Derived_A& ABDerObjPartA = ABDerObj;
ABDerObjPartA.foo();
// more code using ABDerObjPartA.
另一方面,如果——坚持你的术语——foo
的定义真的取决于类而不是实例,那么就把它设为static
:
// In Base:
static void foo()
{
cout << "Class Base foo()" << endl;
}
// in main():
ABDerObj.foo(); // This is now OK
真正应该关注的是,是否真的需要多重继承,尤其是在同一基类多次出现的情况下。通常,一旦你开始遇到这些歧义消除问题,它们就会变得越来越糟,对代码进行一点重新设计会使其更易于维护。
- 关于C++中具有多重继承"this"指针的说明
- C++中模板化异常类的多重继承
- C++继承 - 为什么调用父方法?
- 虚拟继承中是否存在多重继承?
- 如何在 c++ 多重继承中调用父非虚函数?
- 多重继承相同的方法名,没有歧义
- 使用enable_if解决多重继承歧义
- 多重继承导致虚假的模糊虚拟函数过载
- 多重继承和访问不明确的元素
- C++ 多重继承:使用基类 A 的实现实现基类 B 的抽象方法
- 多重继承中的派生类的行为类似于聚合
- 为什么我的 Hippomock 期望在使用多重继承时失败
- 带有此指针的模板类多重继承构造函数不起作用?
- 使用多重继承时出现编译错误
- 为什么在多重继承的情况下,QObject需要成为第一个
- 没有函数重写的多重继承.为什么模棱两可
- 为什么避免类中的多重继承
- 当使用多重继承时,为什么这个限定名称不明确
- 为什么多重继承会增加对象的大小,尽管基基是空的
- 为什么多重继承具有不同签名的方法是不明确的