I'm in a situation like this:
class Callee {
public:
void request();
};
class Caller {
void call() {
Callee{}.request();
}
void invoke1(); // the implementation doesn't matter
void invoke2(); // the implementation doesn't matter
// more invoke()s
};
I want Callee::request()
to request invocation of one of the Caller::invoke()
member functions depending on the context which can be computed either in Callee::request()
or in Caller::call()
:
void Callee::request() {
// do stuff
switch (context) {
// request one of the invoke()s to be run immediately
}
// do more stuff
}
Which solutions would be elegant? I don't want (from most to least important):
Callee
to know the definition of Caller
;Callee
to know the declaration of Caller
;Caller
to choose an invoke()
on its own;It's OK if Callee::request()
receives some arguments from the Caller
.
There is a number of ways you can achieve this.
The most straightforward is to have Callee::request()
return an
enum
value, which the Caller
then does a switch
on and invokes
an appropriate function. This means that caller and callee will have
to both know this enum
.
Another way which is also in straightforward territory, though
slightly more convoluted, is to pass a single function from the
caller to the callee, which accepts that enum
value as a parameter,
so that by invoking this function the callee can indicate to the caller
what it wants done. Again the caller can switch
on that value and
invoke either invoke1()
or invoke2()
or what have you.
Another way is to define an interface, (a class consisting of only
pure virtual methods,) which contains invoke1()
and invoke2()
have the caller implement that interface, and pass that interface of
itself to the callee, so that the callee can decide which function to
call. In this case, caller and callee will need to both have
knowledge of this new interface.
Another way is to pass the callee two pointers to functions, so that the callee can decide which one to call. This way the callee does not need to know anything, but it does not scale very well, because what if you have 50 different functions?