多重继承相同的方法名,没有歧义

Multiple inheritance same method name and no ambiguity

本文关键字:歧义 方法 多重继承      更新时间:2023-10-16

我有两个类(A0和A1(有一个函数foo((,一个A0有一个只调用foo((的函数bar((。以及从 A0 和 A1 继承的 B 类。

B 除了从 A0 和 A1 继承之外什么都不做。

为什么打电话给B->bar()时没有歧义?

一个小代码示例

class A0
{
protected:
/*virtual*/ void foo() {std::cout << "A0" << std::endl; }
public:
void bar() {foo(); }
};
class A1
{
protected:
/*virtual*/ void foo() {std::cout << "A1" << std::endl; }
};
class B : public A0, public A1
{
protected:
//virtual void foo() override {A1::foo(); }
};
int main()
{
B *lPtr = new B;
lPtr->bar(); //"A0" without the override, "A1" with the override
delete lPtr;
return 0;
}

如果我取消注释虚拟和函数覆盖,仍然没有歧义,但它调用另一个 foo。

为什么仍然没有歧义,为什么它称另一个?

如果你有virtual,你的vtable中有两个foo

第一个是A0::foo第二个是A1::foo.

B中覆盖foo时,将覆盖两者,并指示它调用A1::foo()

如果不覆盖B中的foo,则两个foo将保留在 vtable 中,除了名称外不相关。

A0::bar中,当你调用foo()时,它会在本地查找foo。 它看到一个 -A0::foo- 这是虚拟的。 因此,它将调用编码到 vtable 中以执行A0::foo

如果没有B中的覆盖,调用A0::foo。 在B中使用覆盖时,这将调用B::foo然后调用A1::foo

如果你没有virtual,好吧,除了vtable位之外,同样成立。

您有两个函数A0::fooA1::foo。 使用指向A0的指针,->foo()调用A0::foo

使用指向B的指针,->foo()是模棱两可的。

如果您编写一个B::foo方法(无论它是否是虚拟的(都无关紧要,那么B->foo()调用它。


两个事物共享一个名称的事实并不意味着它们是同一事物,也不会使所有调用都模棱两可。

仅当您无法从上下文中分辨出要命名的调用时,调用才不明确。