实施第三方方法虚拟化
我正在扩展第三方库提供的类。该类(我们称之为 Foo
)有一个 reset()
方法,可以调用该方法来重新启动 Foo
的行为。 reset()
方法也在类内部使用。
class Foo
{
public:
void reset () {
/* ... */
}
void something () {
reset();
}
};
到目前为止,我需要重载 reset()
方法才能重置我的附加功能:
class Bar : public Foo
{
public:
void reset() {
/* ...something... */
Foo::reset();
}
};
不幸的是,由于 Foo::reset()
方法不是虚拟的,通过调用 Bar::something()
我调用了 Foo::reset()
方法,而不是 Bar::reset()
。
有没有办法(也不同于重载 Foo::something() )使其成为向后虚拟?
I'm extending a class provided by a third part library. The class, let's call it Foo
, has a reset()
method which can be called in order to restart Foo
's behavior. The reset()
method is also used internally by the class.
class Foo
{
public:
void reset () {
/* ... */
}
void something () {
reset();
}
};
So far, I need to overload the reset()
method in order to reset my additional features as well:
class Bar : public Foo
{
public:
void reset() {
/* ...something... */
Foo::reset();
}
};
Unfortunately, since the Foo::reset()
method is not virtual, by calling Bar::something()
I get the Foo::reset()
method called instead of Bar::reset()
.
Is there a way (different from overloading Foo::something()
as well) to make it backward-virtual?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您不能扩展不打算扩展的类。
You cannot extend classes that were not intended to be extended.
您不能在库中将
reset()
设为虚拟,以免影响基类而不更改基类的代码。对于初学者来说,编译器没有添加必要的簿记代码来允许它对reset()
进行虚拟调用。You can't make
reset()
virtual in your library in such a way that it will affect the base class without changing the base class's code. For starters, the compiler has not added the necessary bookkeeping code that allows it to make virtual calls toreset()
.没有使用继承来做到这一点的“干净方法”。虚拟是编译/链接时间差异:使用 vtable 在运行时解析方法(虚拟)与直接链接(非虚拟)。
There is no 'clean way' of doing it using inheritance. Virtual is a compile/link time difference: using a vtable to resolve method at runtime (virtual) vs direct linking (non-virtual).
不,这是不可能的。方法的虚拟性是在声明方法时决定的,以后不能在基类中更改它。
让你这样做无异于一场灾难。虚拟方法的行为与非虚拟方法不同,在设计对象时必须考虑到这一点。根据这个建议,我必须考虑我的所有方法都可以以两种截然不同的方式表现。这显着增加了应用的设计成本并降低了可靠性。
No this is not possible. The virtualness of a method is decided when the method is declared and you cannot change it later in a base class.
To allow you to do so would be nothing short of a disaster. Virtual methods simply behave differently than non-virtual methods and it must be accounted for when designing an object. With this proposal I would have to consider that all of my methods could behave in 2 distinctly different ways. That significantly adds to the design cost of the application and reduces the reliability.
如果既没有重置也没有虚拟的东西,那么你就完蛋了,故事就到此为止了。如果某些东西是虚拟的,你可以覆盖它。但是,如果这些必要的方法不是虚拟的,则该类不会被扩展(或正确实现,如果有意的话)。
编辑:
你可以尝试组合,例如
,但是如果你需要整个隐式转换,你仍然会被塞满。
If neither reset nor something are virtual, you're screwed, and that's the end of the story. If something is virtual you could override it. However, if these necessary methods aren't virtual, then the class isn't intended to be extended (or implemented properly, if it was intended).
Edit:
You COULD try composition, e.g.
But if you need the whole, implicit conversion, thing, you're still stuffed.