在不指向对象的情况下调用虚方法?

calling virtual method without pointing to an object?

#include <iostream>

struct A {
    void init()
    {
        internal_init();
    }
    virtual void internal_init()
    {
        std::cout << "internal of A" << std::endl;
    }
};

struct B: public A {
    void internal_init()
    {
        init();
        std::cout << "internal of B" << std::endl;
    }
};

int main(){
    B instance;
    std::cout << "internal of A" << std::endl;
    instance.internal_init();
    return 0;
}

首先,程序按预期进入 B::internal_init()。 然后,到 A::init()(我想因为 B 派生自 A ,而 B 没有任何 init())。 现在怎么办?

它会选择什么internal_init()?因为到了B::internal_init(),程序会进入死循环,我不明白为什么。

因为 instanceB

instance.internal_init();

将调用 Bs internal_init()。然后在 internal_init() 中调用 init();。现在成员函数有一个隐式参数,即 this 指针。

所以当我们调用Ainit()时,这个指针实际上是一个B。在 init() 中,我们使用指向 B 的 this 指针调用 internal_init();。由于 internal_init() 是虚拟的并且我们有一个指向 B 的指针,因此虚拟查找机制将调用 Binternal_init().

这将再次循环并最终导致段错误或堆栈溢出。

首先struct B因为struct B: public A继承了struct A的所有功能。 A 的函数 internal_initB 中被覆盖,因为您在 A.

中使用相同的函数签名和关键字 virtual

所以现在调用是: instance.internal_init(); 调用 Binternal_init(),调用 A::init,调用 B::internal_init(),等等,直到给出分段错误。 为了防止这种情况(我认为这就是你想要的),你可以在 B 中显式调用 Ainternal_init() 而不是调用 init():

struct B: public A {
    virtual void internal_init()
    {
        A::internal_init();
        std::cout << "internal of B" << std::endl;
    }
};