强制调用基类虚函数

时间:2012-03-15 16:50:40

标签: c++ class function inheritance virtual

我有一些像这样的事件

class Granpa // this would not be changed, as its in a dll and not written by me
{
public:

   virtual void onLoad(){}

}

class Father :public Granpa // my modification on Granpa
{
public:

    virtual void onLoad()
    {
       // do important stuff
    }

}

class Child :public Father// client will derive Father
{

   virtual void onLoad()
   {
       // Father::onLoad(); // i'm trying do this without client explicitly writing the call

       // clients code
   }
}

有没有办法强制调用onLoad而不实际编写父:: onLoad()

欢迎Hackish解决方案:)

4 个答案:

答案 0 :(得分:26)

如果我理解正确,您需要它,以便每当调用overriden函数时,必须始终首先调用基类实现。在这种情况下,您可以调查template pattern。类似的东西:

class Base
{
public:
    void foo() {
        baseStuff();
        derivedStuff();
    }

protected:
    virtual void derivedStuff() = 0;
private:
    void baseStuff() { ... }
};

class Derived : public Base {
protected:
    virtual void derivedStuff() {
        // This will always get called after baseStuff()
        ...
    }
};

答案 1 :(得分:3)

如上所述,但适用于您的情况。

class Father :public Granpa // my modification on Granpa
{

public:

    virtual void onLoad()
    {
       // do important stuff
       onLoadHandler();
    }
    virtual void onLoadHandler()=0;
}

class Child :public Father// client will derive Father  
{

   virtual void onLoadHandler()
   {

       // clients code
   }
}

但是,没有任何东西可以阻止Child覆盖onLoad,因为c ++没有final关键字,而Granpa onLoad本身就是虚拟的。

答案 2 :(得分:3)

嗯,没有广为人知的,公认的方法来做到这一点。如果有的话,使用事件和信号的GUI库可能已经实现了它。但是,您的问题还有其他解决方案。

您可以使用boost.Signals,sigslot或您自己制作的东西来实现信号 - 事件连接。正如GTK +所做的那样:

g_signal_connect(my_wdg, "expose-event", G_CALLBACK(my_func), NULL);

gboolean my_func(...)
{
    // do stuff 
    return FALSE; /* this tells the event handler to also call the base class's slot */
}

以较少以C为中心的方式,可以按照以下方式实施:

/* In Granpa */
/* typedef a functor as 'DerivedEventHandler' or use a boost::function */
std::vector< DerivedEventHandler > handlers;

void connect(DerivedEventHandler event) { handlers.push_back(event); }

/* in loop */
while (! iter = handlers.end() ) /* call event */

/* In constructor of Father */
this->connect( this->OnLoad );

/* In constructor of Child */
this->connect( this->OnLoad );

/* and so on... in all derived classes  */

答案 3 :(得分:-1)

如果有问题的对象小而便宜,只需调用基类的复制构造函数,即BaseClass(* derived_class_object).method()