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++ 中更有意义。
好久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++ 中更有意义。