自动代理类

时间:2012-04-19 12:43:27

标签: c++ templates design-patterns macros proxy-classes

假设我有一个界面

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

我需要一个代理类,为指针映射做一些id

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);
    }

}

所以我写的时候

Proxy *p;
p->f(1);
在id = 1

的对象上调用

有几种这样的情况,接口相当大。 所以我不想编写代理类中的所有函数。 有没有办法自动完成?也许使用宏,模板,重载“ - >”等

3 个答案:

答案 0 :(得分:6)

简单的解决方案是定义一个运算符 - >返回指向接口的指针。但这会打破你的封装,因为每个人都可以直接访问你的对象而你实际上不需要你的代理类(你可能只需要使用std :: map)。

替代方案你可以做点什么

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...); }
};

它严重依赖于C ++ 11的功能,因此可能无法使用编译器进行编译。

首先它使用Variadic模板。有关详细信息,请参阅https://en.wikipedia.org/wiki/Variadic_Templates

接下来它使用decl_type。有关详细信息,请参阅https://en.wikipedia.org/wiki/Decltype

你必须像这样使用它:

  Proxy<I> p;
  ...

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

答案 1 :(得分:0)

我不知道这是否适合你,但你可以使用函数指针来处理这个......

#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...
}

答案 2 :(得分:0)

另一个解决方案。

http://coliru.stacked-crooked.com/a/857329ab4433a3a9

  #include <iostream>

  template <class F, class... Args>
  inline decltype(auto) invoke(F&& f, Args&&... args) 
     //-> decltype(std::forward<F>(f)(std::forward<Args>(args)...)
  { 
    return std::forward<F>(f)(std::forward<Args>(args)...);
  }

  int main()
  {
     using namespace std;

     cout<<"hello"<<endl;

     struct RaiiProxy {
        RaiiProxy(){
           cout<<"RaiiProxy in"<<endl;
        }
        ~RaiiProxy(){
           cout<<"RaiiProxy out"<<endl;
        }
     };
     auto proxy = [](auto&&f,auto&&...args){
        RaiiProxy raii;
        return invoke( forward<decltype(f)>(f), std::forward(args)... );
     };

     // Use as function
     proxy( [](){ cout<<"I am in proxy."<<endl; } );

     // Use raii
     {  RaiiProxy raii;
        cout<<"I am in RaiiProxy."<<endl;
     }

     cout<<"bye."<<endl;
  }