我正在扩展第三部分库提供的课程。我们称之为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()
)使其向后虚拟?
答案 0 :(得分:5)
您无法扩展不打算扩展的类。
答案 1 :(得分:3)
您不能在库中创建reset()
虚拟,这样它将影响基类而不更改基类的代码。对于初学者,编译器没有添加必要的簿记代码,允许它对reset()
进行虚拟调用。
答案 2 :(得分:2)
使用继承没有“干净的方法”。 Virtual是编译/链接时差:使用vtable在运行时(虚拟)与直接链接(非虚拟)解析方法。
答案 3 :(得分:1)
不,这是不可能的。声明方法时会确定方法的虚拟性,以后不能在基类中更改它。
允许你这样做将是一场灾难。虚拟方法的行为与非虚拟方法的行为不同,在设计对象时必须考虑到这一点。有了这个提议,我将不得不考虑我的所有方法都可以采用两种截然不同的方式。这显着增加了应用程序的设计成本并降低了可靠性。
答案 4 :(得分:1)
如果既不是重置也不是虚拟的东西,那你就搞砸了,这就是故事的结局。如果某些东西是虚拟的,你可以覆盖它。但是,如果这些必要的方法不是虚拟的,那么该类不应该被扩展(或者如果有意的话,可以正确实现)。
编辑:
你可以尝试组合,例如
class Bar {
Foo f;
// foo's methods, etc, wrapped here
void something() {
f.reset();
reset();
}
};
但是如果你需要整个隐式转换,那么你仍然会被塞满。