【问题标题】:Automatic Proxy Class自动代理类
【发布时间】:2012-04-30 23:35:57
【问题描述】:

假设我有一个接口

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 的对象上调用 f

这样的案例很多,接口比较大。 所以我不想编写代理类中的所有函数。 有没有办法自动完成?可能使用宏、模板、重载“->”等。

【问题讨论】:

  • 您是否为许多接口编写了相同的代理,或者为同一接口编写了许多代理类,或者为许多接口编写了许多代理?
  • 这有点令人困惑:看起来像这样,我的实例不知道他自己的索引,但它知道什么时候调用了他的 f 或 g 方法......为什么?奇怪的设计。我会在不知道他自己的索引的情况下计划整个事情。那会更有意义。
  • @hansmaad,许多接口的许多代理(一对一)
  • 我不认为有一个干净的解决方案。我最好的想法是区分 I 类的行为,因此如果它的一个对象是使用某个标志创建的,它宁愿充当自身其他实例的代理。您必须在每个成员函数的开头放置一些代码,以检查当前实例是否为代理,如果是,则在请求的实例上调用相同的方法。这可以通过宏来完成。
  • p->get(i)->f() 有什么问题?

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


【解决方案1】:

简单的解决方案是定义一个返回接口指针的操作符->。但这会破坏您的封装,因为每个人都可以直接访问您的对象,而您实际上不需要您的代理类(您不妨只使用 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 特性,因此它可能无法使用您的编译器进行编译。

首先它使用可变参数模板。请参阅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.);

【讨论】:

  • 哇!我们没有兼容 C++11 的编译器,但是,这真是太棒了!谢谢!
  • 好吧,我想这是我能得到的最好的:)
  • 我们不需要std::forward&lt;Param&gt;(params...)...吗?
【解决方案2】:

我不知道这是否适合你,但你可以使用指向函数的指针来解决这个问题......

即。

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

【讨论】:

    【解决方案3】:

    另一种解决方案。

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

    【讨论】:

      猜你喜欢
      • 2013-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-29
      • 2019-04-15
      • 1970-01-01
      • 2013-03-21
      • 1970-01-01
      相关资源
      最近更新 更多