简体   繁体   English

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

[英]Multiple inheritance same method name and no ambiguity

I have two classes (A0 and A1) that have a function foo() and a A0 has a function bar() that just calls foo(). 我有两个类(A0和A1),它们具有一个函数foo(),而一个A0具有一个函数bar(),它仅调用foo()。 And a class B that inherits from A0 and A1. 还有从A0和A1继承的B类。

B does nothing beside inheriting from A0 and A1. 除了从A0和A1继承外,B不执行任何操作。

Why is there no ambiguity when calling B->bar() ? 为什么在调用B->bar()时没有歧义?

A small code sample 一小段代码示例

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;
}

And if I uncomment the virtual and the function override, there is still no ambiguity but it calls the other foo. 而且,如果我取消注释虚函数和函数重写,则仍然没有歧义,但会调用另一个foo。

Why is there still no ambiguity and why does it call the other one? 为什么仍然没有歧义,为什么又称另一个歧义?

In the case you have virtual there are two foo s in your vtable. 如果您有virtual ,则您的vtable中有两个foo

The first one is A0::foo the second one is A1::foo . 第一个是A0::foo ,第二个是A1::foo

When you override foo in B , you override both , and instruct it to call A1::foo() . 当您在B覆盖foo时,您将覆盖两者 ,并指示它调用A1::foo()

If you don't override foo in B , the two foo s remain in the vtable, unrelated except by name. 如果不重写fooB ,这两个foo S保持存储在虚表,除了按名称无关。

In A0::bar , when you call foo() it looks locally for a foo . A0::bar ,当您调用foo()它将在本地查找foo It sees one -- A0::foo -- which is virtual. 它看到一个A0::foo是虚拟的。 So it encodes a call into the vtable to execute A0::foo . 因此,它将调用编码到vtable中以执行A0::foo

Without the override in B the invokes A0::foo . 如果B没有覆盖,则调用A0::foo With the override in B this invokes B::foo when then calls A1::foo instead. 有了B的覆盖,它会在调用A1::foo时调用B::foo

In the case you don't have virtual , well, the same holds except the vtable bit. 在您没有virtual的情况下,除了vtable位之外,其他保持不变。

You have two functions A0::foo and A1::foo . 您有两个函数A0::fooA1::foo With a pointer to A0 , ->foo() invokes A0::foo . 使用指向A0的指针, ->foo()调用A0::foo

With a pointer to B , ->foo() is ambiguous. 使用指向B的指针, ->foo()是不明确的。

If you write a B::foo method (does not matter if it is virtual), then B->foo() invokes it. 如果编写B::foo方法(是否为虚拟方法无关紧要),则B->foo()调用它。


The fact that two things share a name doesn't mean they are the same thing, nor does it make all calls ambiguous. 两件事共享一个名字的事实并不意味着它们是同一件事,也不意味着所有调用都是模棱两可的。

The calls are ambiguous only if you cannot tell which one is being named from context. 仅当您无法从上下文中命名哪个调用时,这些调用才是模棱两可的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM