cpp继承虚方法解析顺序

cpp inheritance virtual method resolution order

好久reader第一次来这里问

我正在尝试通过继承外部库来扩展它的功能。

在库中有一个基础 class 和一个从它派生并实现一些低级功能的基础,然后是我从后者派生的实现。

这是实现的一个简单的概念化代码示例:

基础class:

 class A {

    virtual int vf() = 0;

    int get_next(){
        return vf() * 2; 
    } 
};

导出class:

class B : public A {

    virtual int vf(){
        return 1;
    }

};

我的分机图书馆:

class C : public B {

    int vf(){
        return B::get_next() + 1;
    }

};

那我要打电话:

C::get_next();

但这会导致递归函数调用:

C::get_next() = A::get_next() -> C::vf() -> A::get_next() -> C::vf() -> A::get_next() -> C::vf() -> A::get_next() -> C::vf() ... and so on

我希望发生的事情:

C::get_next() = A::get_next() -> C::vf() -> A::get_next() -> B::vf() end of call trace

这可能吗?我在实施中做错了什么或遇到了一些未定义的行为或类似的行为?

B::get_next() 该函数内部仍然有动态调度。

如果可能且合适,您可以切片您的对象:

class C : public B {

    int vf() override
    {
        return B(*this).get_next() + 1;
    }
};

当你调用C::get_next()时,它实际上调用了A::get_next(),然后调用了在C中重载的vf()。之后调用了B::get_next()这实际上再次调用 A::get_next() 导致 vf() (再次在 C 而不是 B 中重载)再次调用并重复。您无法通过如此混乱的设计真正实现您想要的。如果你想要这样的电话: A::get_next() -> C::vf() -> A::get_next() -> B::vf()

您可能需要像这样重写该基 class 的一些代码:

int vf(){
  return B::vf() * 2 + 1;
}

基本上就是这样 A::get_next() -> C::vf() -> B::vf() 实际上在 C++ 中更有意义。