I have my fancyFunction which takes a set of elements implementing interface A. The function does a complicated analysis of those elements, based on properties read through interface A. During this analysis, it will call methods of a Consumer c which will take the elements as arguments.
The Consumer is designed to take arguments of a specific type which has absolutely nothing to do with A.
You could imagine that A is an abstraction for edges in a graph. The graph is analyzed in fancyFunction and - for example - every time the function "crosses" an edge, it will send that edge to a Consumer which prints additional information stored in the edge that has nothing to do with it being an edge.
The code given below would of course not compile in a typed language (particularly C++), but leaving out the types (Matlab, Python), the code would work.
To make it work in a typed language (particularly C++), I see two options:
-
Declare the function as
template <class CONSUMER> void fancyFunction(A[] setOfAs, CONSUMER c){ ... } -
Declare
operation1andoperation2to take the most general object and then do a downcast in the implementation.
What do you recommend to do in that situation? (As far as I see, the visitor pattern is NOT an option.)
Full code outline (I did not use C++ in a while, so please excuse if there are minor syntactical mistakes.):
void fancyFunction(A[] setOfAs, Consumer* c){
// do fancy analysis of setOfAs by properties
// read through interface A
double x = setOfAs[i]->getX();
// call functions in c with arguments of setOfAs[j]
...
c->operationX(setOfAs[i]);
...
c->operationY(setOfAs[j]);
...
}
class A{
virtual double getX();
}
class Consumer{
virtual void operationX(??? x); // whoops, what type do we expect?
virtual void operationY(??? y); // whoops, what type do we expect?
}
class Consumer1{
void operationX(Obj1 x){ ... } // whoops, override with different type
void operationY(Obj1 y){ ... } // whoops, override with different type
}
class Consumer2{
void operationX(Obj2 x){ ... } // whoops, override with different type
void operationY(Obj2 y){ ... } // whoops, override with different type
}
class Obj1 : public A {};
class Obj2 : public A {};
void test(){
Obj1 o1[];
Obj2 o2[];
Callback1 c1;
Callback2 c2;
fancyFunction(o1, &c1);
fancyFunction(o2, &c2);
}
Aucun commentaire:
Enregistrer un commentaire