简体   繁体   English

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

[英]If an overridden C++ function calls the parent function, which calls another virtual function, what is called?

I'm learning about polymorphism, and I am confused by this situation: Let's say I have the following C++ classes: 我正在学习多态性,我对这种情况很困惑:假设我有以下C ++类:

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

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

I create an instance of B and call its Foo() function. 我创建了一个B实例并调用它的Foo()函数。 When that function calls A::Foo(), will the Boo() method used be that of class A or B? 当该函数调用A :: Foo()时,使用的Boo()方法是A类还是B类? Thanks! 谢谢!

Unless you qualify a function call with the class, all method calls will be treated equal, that is dynamic dispatch if virtual, static dispatch if not virtual. 除非您使用类限定函数调用,否则所有方法调用都将被视为相等,即动态分派(如果是虚拟),静态分派(如果不是虚拟)。 When you fully qualify with the class name the method you are calling you are effectively disabling the dynamic dispatch mechanism and introducing a direct method call. 当您完全使用类名限定时,您调用的方法实际上是禁用动态调度机制并引入直接方法调用。

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

The implicit this pointer is not an important part of the discussion here, as exactly the same happens when the call is made with an explicit object: 隐式this指针不是这里讨论的重要部分,因为使用显式对象进行调用时会发生完全相同的情况:

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

Note 1: in this example, the compiler can elide the dynamic dispatch mechanism as it knows the concrete type of the instance (it sees the definition and it is not a reference/pointer) but you can imagine the same would happen if b was a reference, or equivalently if it was a pointer with -> instead of . 注1:在这个例子中,编译器可以忽略动态调度机制,因为它知道实例的具体类型(它看到定义并且它不是引用/指针)但你可以想象,如果b是a,那么同样会发生引用,或等效地,如果它是一个指针->而不是.

Since Boo() is virtual, the derived class' override is called. 由于Boo()是虚拟的,因此调用派生类的覆盖。

Boo(); is just a short-hand for this->Boo(); 这只是一个简写 - this->Boo(); , where you can see that a virtual function is called through a pointer . ,您可以看到通过指针调用虚函数 ( this is of type A* const within Foo() .) And virtual functions called through a reference or a pointer will always call the override in the most-derived class (except when called from a constructor or destructor). thisFoo() A* const类型。)通过引用或指针调用的虚函数将始终在最派生类中调用覆盖(除非从构造函数或析构函数调用)。

Inside A, 在A里面,

virtual void Foo(){
        Boo();
    }

gets translated to this->Boo() ;since Boo is declared virtual in A, the derived class's method Boo gets called. 被转换为this->Boo() ;因为Boo在A中被声明为虚拟,所以派生类的方法Boo被调用。 Try not declaring Boo as virtual in A just for experimentation -- you'd see that A->Boo() is getting called. 尽量不要将Boo声称为A中的虚拟实验 - 你会看到A-> Boo()被调用。

Arpan Arpan

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

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