在内部(运行时)如何决定要调用的函数是基类函数还是派生类函数。在下面的示例代码中,如何决定调用B的fn()和A的fn2()。

Class A {
    virtual void fn() { std::cout << "A" < <std::endl; }
    virtual void fn2() { std::cout << "A-fn2" < <std::endl; }
    };

Class B : A
{
    void fn() { std::cout << "B" < <std::endl; }
}

int main() {
    B b = new B;
    A *a = &b;
    a->fn();
    a->fn2();
}


输出将是B和A-fn2()

基本上,在运行时如何决定是调用派生类函数还是基类函数?

最佳答案

您所拥有的被称为动态/运行时多态。
规则是:
在运行时选择在运行时调用的方法,具体取决于指针指向的实际对象。
编译器如何做到这一点完全取决于实现。通常,您的代码应仅依赖于行为,而不是依赖于内部行为。但是,所有已知的编译器都通过虚拟表(vtbl)和虚拟指针(vptr)机制来实现此机制。

运行时多态如何实现?

一旦一个类具有virtual方法,该类就称为多态类,并且编译器会为该类创建一个vtblvtbl存储该类中所有虚拟方法的地址。编译器还为该类的每个对象添加了特殊的指针vptrvptr指向(存储地址)到vtbl
从此类多态类派生出一个类后,编译器将派生类的vtbl中方法的地址替换为派生类中重叠函数的地址。方法。

因此,每个类通常都有一个vtbl,而每个对象实例都有一个vptr,该vtbl指向vtbl。每个类的vptr存储其自己的虚拟方法的地址。

在运行时,将获取this指针内的vtbl,并进一步获取中的相应方法地址,然后将其调用,此机制称为动态调度。
因此,由于这种机制,可以根据指针所指向的对象的类型来确定要调用的适当方法。

这个C ++-Faq是一个很好的进一步阅读:
Inheritance — virtual functions

10-02 02:28