如果被重写的C ++函数调用父函数,该函数调用另一个虚函数,则调用什么?

时间:2010-06-29 13:40:04

标签: c++ polymorphism

我正在学习多态性,我对此情况感到困惑: 假设我有以下C ++类:

class A{
    ...
    virtual void Foo(){
        Boo();
    }
    virtual void Boo(){...}
}

class B : public A{
    ...
    void Foo(){
        A::Foo();
    }  
    void Boo(){...}
}

我创建一个B实例并调用它的Foo()函数。当该函数调用A :: Foo()时,使用的Boo()方法是A类还是B类?谢谢!

3 个答案:

答案 0 :(得分:9)

除非您使用类限定函数调用,否则所有方法调用都将被视为相等,即动态分派(如果是虚拟),静态分派(如果不是虚拟)。当您使用类名完全限定时,您调用的方法实际上是禁用动态调度机制并引入直接方法调用。

class A{
    virtual void Foo(){
        Boo();           // will call the final overrider
        A::Boo();        // will call A::Boo, regardless of the dynamic type
    }
    virtual void Boo();
};
class B : public A{
    void Foo(){
        //Foo();         // Would call the final overrider 
                         // (in this case B: infinite recursion)
        A::Foo();        // Will call A::Foo, even if the object is B
    }  
    void Boo();
};

隐式this指针不是此处讨论的重要部分,因为使用显式对象进行调用时会发生完全相同的情况:

B b;
b.Foo();    // will call B::Foo -- note 1
b.A::Foo(); // will call A::Foo

注1:在这个例子中,编译器可以忽略动态调度机制,因为它知道实例的具体类型(它看到定义并且它不是引用/指针)但是你可以想象如果发生同样的情况会发生b是一个引用,或者相当于它是一个指针->而不是.

答案 1 :(得分:2)

由于Boo()是虚拟的,因此调用派生类'覆盖。

Boo();只是this->Boo();的简写,您可以在其中看到通过指针调用虚拟函数。 (thisA* const中的类型为Foo()。)通过引用或指针调用的虚函数将始终在最派生类中调用覆盖(从构造函数调用时除外)或析构函数)。

答案 2 :(得分:1)

在A里面,

virtual void Foo(){
        Boo();
    }

被转换为this->Boo();因为Boo在A中被声明为虚拟,所以派生类的方法Boo被调用。尽量不要将Boo声称为A中的虚拟实验 - 您会看到A-> Boo()被调用。

Arpan