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

时间:2018-08-22 19:39:27

标签: c++ inheritance

我有两个类(A0和A1),它们具有一个函数foo(),而一个A0具有一个函数bar(),它仅调用foo()。还有从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。

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

1 个答案:

答案 0 :(得分:0)

如果您有virtual,则您的vtable中有两个foo

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

当您覆盖foo中的B时,您覆盖两个 ,并指示它调用A1::foo()

如果您未覆盖foo中的B,则两个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()会调用它。


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

仅当您无法从上下文中命名哪个调用时,这些调用才是模棱两可的。