2012-04-19 14 views
7

Supongamos que tengo una interfazclase proxy automático

class I{ 
public: 
    virtual void f(int id)=0; 
    virtual void g(int id, float x)=0; 
} 

necesito una clase de proxy, hacer algún tipo de identificación para el mapeo puntero

class Proxy : I 
{ 
    I * i[5]; 
public: 
    void f(int id) 
    { 
     i[id]->f(id); 
    } 

    void g(int id, float x) 
    { 
     i[id]->g(id, x); 
    } 

} 

Así que cuando escribo

Proxy *p; 
p->f(1); 

f se invoca en el objeto con id = 1

hay varios casos similares y las interfaces son bastante grandes. Así que no quiero codificar todas las funciones en la clase de proxy. ¿Hay forma de hacerlo automáticamente? tal vez el uso de macros, plantillas, sobrecarga "->", etc.

+0

¿Hay muchas interfaces que escribe el mismo proxy para, o muchas clases de proxy para la misma interfaz, o muchos sustitutos para muchas interfaces? – hansmaad

+0

es un poco confuso: se ve así y una instancia de I no conoce su propio índice, pero llega a saber cuándo se llaman sus métodos f/g ... ¿por qué? diseño extraño Planearía todo con nunca conocer su propio índice. Eso tendría un mejor sentido. –

+0

@hansmaad, muchos proxies para muchas interfaces (uno a uno) –

Respuesta

4

La solución fácil es definir un operador-> que devuelve el puntero a la interfaz. Pero esto romperá su encapsulamiento ya que todos pueden acceder a sus objetos directamente y usted realmente no necesita su clase proxy (también podría usar un std :: map).

alternativa que podría hacer algo como

template <typename Interface> 
class Proxy 
{ 
    Interface* interfaces[5]; 
public: 
    template <typename F, typename... Params> 
    auto operator()(F f, const int id, Params... parameters) 
      -> decltype((interfaces[id]->*f)(id, parameters...)) 
    { return (interfaces[id]->*f)(id, parameters...); } 
}; 

Es en gran medida se basa en C++ 11 rasgos lo que no podría compilar con el compilador.

Primero usa las plantillas de Variadic. Consulte https://en.wikipedia.org/wiki/Variadic_Templates para obtener más información.

A continuación, utiliza tipo_de_decisión. Ver https://en.wikipedia.org/wiki/Decltype para más información.

Hay que utilizar de esta manera:

Proxy<I> p; 
    ... 

    p(&I::f,1); 
    p(&I::g,3, 1.); 
+0

¡woow! no tenemos un compilador compatible con C++ 11 pero, ¡esto es simplemente hermoso! ¡Gracias! –

+0

¿Puede entonces aceptar la respuesta :-) – BertR

+0

bien, supongo que esto es lo mejor que puedo conseguir :) –

0

No sé si esto es adecuado para usted, pero usted podría hacerse cargo de esto utilizando punteros a funciones ...

decir.

#include <stdio.h> 

typedef void (*f)(int); 

void f1(int a) 
{ 
    printf("f1: %d\n", a); 
} 
void f2(int a) 
{ 
    printf("f2: %d\n", a); 
} 
int main(int argc, char *argv[]) 
{ 
    f array[5] = {NULL}; // create array of pointers 
    array[0] = f1; // assign different functions on them 
    array[1] = f2; // -||- 

    array[0](10); // call them 
    array[1](12); 

    // and you end up with something like "array[i]();" in your proxy class... 
} 
Cuestiones relacionadas