1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| #include <iostream>
class base_object
{
public:
virtual ~base_object() { }
}; // class base_object
// classe mère pour la classe exec::caller ci-dessous
class base_caller
{
public:
virtual void run(base_object& i) const = 0;
}; // class base_caller
// Cette classe définit une dérivée de base_caller pour appeler une méthode de
// la classe C, de type de retour R et dont les paramètres sont de type A1, ...,
// An. Une instance de ce caller est crée.
template< typename C, typename R, typename A1, typename A2,
R (C::*method_name)(A1, A2) >
class exec
{
public:
typedef R (C::*method_type)(A1, A2);
public:
class caller:
public base_caller
{
public:
virtual void run(base_object& i) const
{
C& inst( dynamic_cast<C&>(i) );
const method_type m(method_name);
(inst.*m)(1, 0);
}
}; // class caller
static caller instance;
}; // class exec
template< typename C, typename R, typename A1, typename A2,
R (C::*method_name)(A1, A2) >
typename exec<C, R, A1, A2, method_name>::caller
exec<C, R, A1, A2, method_name>::instance;
// méthode pour trouver l'instance de exec<>::instance qui convient en fonction
// de la fonction à appeler.
template<typename C, typename R, typename A1, typename A2>
base_caller* maker( R (C::*method_name)(A1, A2) )
{
return &exec<C, R, A1, A2, method_name>::instance;
}
// petit exemple
class T1:
public base_object
{
public:
int test( int a, double b )
{ std::cout << "T1" << std::endl; return 0; }
};
int main()
{
T1 t1;
base_caller* c0 = &exec<T1, int, int, double, &T1::test>::instance;
c0->run(t1);
base_caller* c1 = maker( &T1::test );
c1->run(t1);
return 0;
} |
Partager