【问题标题】:How can one force an overriden methods base method to be called from the overriden method?如何强制从被覆盖的方法中调用被覆盖的方法基方法?
【发布时间】:2020-07-02 09:48:18
【问题描述】:

我有一堂课:

class MyCoolBean {

public:

    virtual void toot(){
        log("ooh la la");
    }
}

还有我的派生类:

class MyCoolBeansBoy : public MyCoolBean{
public:
    void toot()override{
        log("oh yeah");
    }
}

如果我这样做:

MyCoolBeansBoy 男孩; boi.toot();

输出是:

oh yeah

但我希望输出是:

ooh la la
oh yeah

现在我知道我可以将派生函数修改为:

    void toot()override{
        MyCoolBean::toot();
        log("oh yeah");
    }

但如果我这样做,那么任何实现派生类的人都可以简单地忘记。无论如何要强制调用MyCoolBean::toot() 吗?

编辑:我知道这在技术上是可行的,因为这个问题的答案:

How to ensure that every method of a class calls some other method first?

上面链接中的解决方案可以用来强制所有函数调用一个成员函数!我的问题是如何只为覆盖方法执行此操作,并专门调用基本方法! :)

【问题讨论】:

  • 你不能并且链接问题的接受答案并不能确保调用log log。仍然可以编写LoggingFoo f; f.a();,它会直接调用a,而不会执行log

标签: c++ c++11


【解决方案1】:

你没有。

(因为不可能可靠地做到这一点,所以你的链接中的答案很好,但它只适用于相当受限制的指针)

要么您希望派生方法与基中的方法相同,然后您不将其声明为虚拟,或者...

如果您希望派生类扩展基类方法的功能,那么您可以使用所谓的Template Method Pattern

class MyCoolBean {    
public:   
    void toot() {             // <- not virtual !
        log("ooh la la");
        do_toot();
    }
protected:                
    virtual void do_toot() {}        // <- customization point
};

派生类:

class MyCoolBeansBoy : public MyCoolBean{
private:
    void do_toot() override {
        log("oh yeah");
    }
};

现在

MyCoolBeansBoy x;
x.toot();

将记录两条消息。

这实现了您想要的,但以某种颠倒的逻辑:当基类中的方法被调用时,基类“强制”每个派生类调用派生类的方法。 do_toot 可以是纯虚的,那么派生类就不能忘记提供一个实现。

【讨论】:

    猜你喜欢
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多