mikbal
mikbal

Reputation: 1198

Force calling base class virtual function

I have some events like this

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
   }
}

Is there a way to force calling onLoad without actually writing Father::onLoad()?

Hackish solutions are welcome :)

Upvotes: 23

Views: 10418

Answers (4)

user2037208
user2037208

Reputation: 1

If the object in question is small and cheap to copy, simply call the base class' copy constructor, i.e. BaseClass(*derived_class_object).method()

Upvotes: -1

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272677

If I understand correctly, you want it so that whenever the overriden function gets called, the base-class implementation must always get called first. In which case, you could investigate the template pattern. Something like:

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

Upvotes: 35

ApprenticeHacker
ApprenticeHacker

Reputation: 22031

Well, there is no widely known, recognized way to do this. If there had been, GUI libraries using events and signals would probably have implemented it. However there are other solutions to your problem.

You could implement a signal - event connection, using boost.Signals, sigslot or something of your own making. As GTK+ does:

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 */
}

In a less C-centric way, this could be implemented along these lines:

/* 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  */

Upvotes: 3

dweeves
dweeves

Reputation: 5615

As suggested above but applied to your case.

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
   }
}

However, nothing can prevent Child to override onLoad since c++ has no final keyword and Granpa onLoad is itself virtual.

Upvotes: 3

Related Questions