【问题标题】:Multiple inheritance same method name and no ambiguity多重继承同名且无歧义
【发布时间】:2018-08-22 19:39:26
【问题描述】:

我有两个类(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。

为什么还是没有歧义,又为什么叫对方呢?

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

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

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

    当您在 B 中覆盖 foo 时,您会覆盖 both,并指示它调用 A1::foo()

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

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

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

    如果您没有virtual,那么除了vtable 位之外,同样适用。

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

    使用指向B 的指针,-&gt;foo() 是不明确的。

    如果你编写了一个B::foo 方法(不管它是否是虚拟的),那么B-&gt;foo() 就会调用它。


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

    只有当您无法从上下文中分辨出哪个是被命名时,这些调用才会模棱两可。

    【讨论】:

      猜你喜欢
      • 2016-05-07
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 2011-02-09
      相关资源
      最近更新 更多