2014-09-13 142 views
3

代码场景如下:有没有办法强制调用重写的方法?

class ParentClass { 
    void foo(); 
    virtual void doSomething() { foo(); } 
}; 

class ChildClass : public ParentClass { 
    virtual void doSomething(); 
}; 

现在,有没有办法来迫使子类调用父类的DoSomething的()?假设调用foo()非常重要,并且在调用doSomething()时应始终调用它。孩子班当然可以拨打ParentClass::doSomething(),但它似乎有点“风险”,因为它没有执行。

我想出了一个“脏”的解决方案,它是这样的:

class ParentClass { 
    void foo(); 
    void doSomething() final {foo(); doSomethingChild(); } 
    virtual void doSomethingChild() = 0; 
}; 

class ChildClass : public ParentClass { 
    virtual void doSomethingChild(); 
}; 

这样,子类必须做的实施和foo()总是被调用,但该方法是不一样的了。有没有更优雅的解决方案?

+2

您的“脏”解决方案称为模板方法模式。这对你的问题是一个完美的解决方案。 – 2014-09-13 09:29:42

+0

我很确定你这样做的方式就是这样做的。 – Galik 2014-09-13 09:30:22

+0

@TobiasBrandt出于某种原因,它仍然让我感觉自己像个罪人。 :p – manabreak 2014-09-13 09:33:06

回答

3

这不是一个肮脏的解决方案,而是您自己发现的非虚拟接口习语(或模板方法模式)。

通过定义调用虚函数的非虚函数(除其他外),可以强制类的每个实现都实现非虚函数的行为。该实现只能自由修改此行为的一部分,即对虚函数的调用。

这通常是像这样:

class Base { 
public: 
    void foo() { 
     //do stuff 
     fooImpl(); 
     //do other stuff 
    } 
private: 
    virtual void fooImpl(); //pure or not 
}; 

class Derived : public Base { 
private: 
    virtual void fooImpl(){ 
    // Implement or change fooImpl behavior 
    } 
}; 

使得非虚拟公众和虚拟私有保证,以及没有人可以调用这些类的,这是你想要的,因为你需要一些东西来fooImpl在致电fooImpl之前和/或之后执行。

0

让我们看看会这样工作:

class parent { 
    void foo() {...} 
    virtual void doFinal() {...} 
    void doSomething(){foo(); doFinal();} 
} 

class child { 
    virtual void doFinal() {...} 
} 

所以,你可以重新实现doFinal ANS使用doSmthing。

相关问题