关于多重继承和歧义
About multiple inheritance and ambiguity
在下面的示例中:
class A {
public:
virtual void f() { cout << "a" << endl; }
virtual void h() { cout << "A" << endl; }
};
class s1 : public A {
public:
virtual void f() { cout << "s1" << endl; }
};
class s2 : public A {
public:
virtual void h() { cout << "s2" << endl; }
};
class GS : public s1, public s2 {
public:
};
int main()
{
s1 *q = new GS;
q->h();//no problem
GS a;
a.h();//error
}
为什么a.h();
给出歧义错误,q->h();
没有?
*q
没有一个应该导致相同歧义问题的GS
实例吗?
使用多重继承会导致GS
中出现两个A
实例。当您使用 S1 *q
访问GS
实例时,它会跟随与S1
关联的A
实例。由于S1
不实现h()
,q->h()
的输出将是A
本身提供的实现。
如果您希望q->h()
使用 S2
提供的实现,则需要使用虚拟继承创建菱形。这样做还可以消除使用a.h()
时的歧义,因为虚拟继承只会导致A
的一个实例出现在GS
中。
class s1 : virtual public A {
public:
virtual void f() { cout << "s1" << endl; }
};
class s2 : virtual public A {
public:
virtual void h() { cout << "s2" << endl; }
};
名称查找基于静态类型而不是动态类型。(它必须是,因为它发生在编译时而不是运行时。
因为你的指针是s1
类型,所以编译器知道调用h()
(继承自类A
)。尝试使用类型 GS
的指针,您也会收到指针错误。在你从s1
和s2
继承GS
的情况下,两个类都继承自A
,因此,发现h()
的多个(2)定义是模棱两可的。这是可怕的钻石。
好的,这是因为当编译器计算 q->h() 时,q 的作用域中只有一个名为"h"的函数,因为它的类型为 s1。
当编译器计算 a.h() 时,a 的作用域中有两个名为"h"的函数。来自 s1 的一个和来自 s2 的一个。
编译器不知道要使用哪一个,因此会引发错误。
*q
不会给出歧义错误,因为它的类型是 s1*
。这意味着编译器将调用s1::h
,这是明确的。
相关文章:
- 关于C++中具有多重继承"this"指针的说明
- C++中模板化异常类的多重继承
- 虚拟继承中是否存在多重继承?
- 如何在 c++ 多重继承中调用父非虚函数?
- 多重继承相同的方法名,没有歧义
- 使用enable_if解决多重继承歧义
- 多重继承导致虚假的模糊虚拟函数过载
- 多重继承和访问不明确的元素
- C++ 多重继承:使用基类 A 的实现实现基类 B 的抽象方法
- 多重继承中的派生类的行为类似于聚合
- 为什么我的 Hippomock 期望在使用多重继承时失败
- 带有此指针的模板类多重继承构造函数不起作用?
- 引用如何解决多重继承中的歧义
- 如何处理同一模板多重继承中的歧义
- 消除多重继承中类成员的歧义
- 与 [] 运算符和多重继承的歧义
- 关于多重继承和歧义
- C++多重继承+虚拟函数(-歧义)=怪异行为(也是函数指针)
- c++多重继承有歧义
- 多重继承歧义基类