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