强制实施第三方方法虚拟化

时间:2010-08-31 15:03:19

标签: c++ virtual

我正在扩展第三部分库提供的课程。我们称之为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())使其向后虚拟?

5 个答案:

答案 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();
    }
};

但是如果你需要整个隐式转换,那么你仍然会被塞满。