C++ 通用对象包装器

C++ 通用对象包装器,c++,C++,我想知道是否有一种很好的通用方法来编写对象包装器,这样您就可以调用它包装在包装器类本身上的类定义的所有方法(而不必显式地重新定义包装器类中的类接口)。例如,两个不同的任意类: class InnerExample1 { public: InnerExample1(int a, bool b) {...} void DoSomething1(int a) {...} bool DoSomething2(bool b) {...} etc... }; class I

我想知道是否有一种很好的通用方法来编写对象包装器,这样您就可以调用它包装在包装器类本身上的类定义的所有方法(而不必显式地重新定义包装器类中的类接口)。例如,两个不同的任意类:

class InnerExample1 {
public:
    InnerExample1(int a, bool b) {...}
    void DoSomething1(int a) {...}
    bool DoSomething2(bool b) {...}
    etc...
};

class InnerExample2 {
    InnerExample2(float a, int b) {...}
    void DoWork(int a) {...}
    bool GetResult(bool b) {...}
    etc...
};
我想要一个通用定义的包装类,这样我就可以:

Wrapper<InnerExample1> inner1;
inner1.DoSomething(42);
bool result = inner1.DoSomething2(false);
1;
1.剂量测定法(42);
bool result=inner1.DoSomething2(false);

2;
2.暗销(21);
bool result=inner2.GetResult(true);
“Wrapper”具有足够的通用性,能够处理任何一个类的Wrapper,并将对它的所有调用转发给它的内部委托

我见过类似工厂模式的代码,其中,使用可变参数,泛型工厂可以实例化任何类,以及泛化绑定到单个成员方法,但对整个类没有任何作用。在我看来,这似乎是不可能的……但人们总是想出各种各样我永远不会想到的东西:)

编辑: 我试图通过省略不必要的细节来保持问题的简单,但我遗漏了太多。我需要包装器在每个调用周围插入一些逻辑。比方说,我希望这个包装器能够计算每个方法被调用的次数,并将调用转发给内部对象

编辑2: 具体来说,我试图编写一个通用包装器来实现ActiveObject模式。最后,我做了一个“活动”基类来处理公共位(管理内部线程、排队函数调用),并为每个内部类型编写子类(模仿它们的接口)

编辑3: @id256的答案非常有趣,我想我会在某个时候回来尝试一下该方法。

根据您的评论(和编辑),最接近的方法是在调用方法(或访问属性)之前执行一些逻辑,利用运算符->必须与右侧的方法或属性名称一起使用这一事实。不幸的是,你无法分辨是哪一个

#include <iostream>

template<typename T>
class wrapper {
  T obj;
  public:
  T* operator->() {
    std::cout << "Method called(or attribute accessed). Can't tell which one." << std::endl;
    return &obj;
  }
};

struct wrapped {
  void do_nothing() {}
};

int main() {
  wrapper<wrapped> a;
  a->do_nothing();
}
#包括
模板
类包装器{
T-obj;
公众:
T*运算符->(){

std::cout很有可能,您可以在
包装器
类模板中定义
运算符->
。实际上,这可能类似于:

template <typename T>
class Wrapper {
    T* pT;
public:
// ...
    T* operator->() { return pT; }
// all the needed stuff to manage pT
};
输出:

calling A::inc from Wrapper
A::inc 123
wA.f(123)=124

EDIT2:此外,还可以在
包装器
中重写
操作符->*
并返回某种代理对象,该对象包含指向实例的指针和指向方法的指针。通过这种方法,您可以控制方法的执行时刻,以及对代理对象进行预处理或后处理。该方法的描述可以在

中找到s技术,如果您不能从T继承,您可以覆盖->操作符以授予对包装类的访问权

class Wrapped { 
public: 
    void DoSomething(); 
}; 

template<class T>  
class Wrapper { 
public: 
    T * operator->() { 
        return &t; 
    } 

private: 
    T t; 
}; 

int main() { 
    Wrapper<Wrapped> w; 
    w->DoSomething(); 
} 
类包装{
公众:
无效剂量();
}; 
模板
类包装器{
公众:
T*运算符->(){
返回&t;
} 
私人:
T;
}; 
int main(){
包装纸w;
w->DoSomething();
} 

它不是特别封装的,但是您可以使用一个函数模板,该模板接受一个成员函数指针和一个可变参数包:

template<typename Inner>
class Wrapper {
 private:
  Inner inner;
 public:

  template<typename ...Args>
  Wrapper(Args&&... args) : inner(std::forward<Args>(args)...) { }

  template<typename ...Args, typename R>
  R forward( R (Inner::* function)(Args...), Args &&...args) {
    return (inner.*function)(std::forward<Args>(args)...);
  }
};


Wrapper<InnerExample1> wrapper1(1, true);
wrapper1.forward(&InnerExample1::DoSomething1, 42);
bool result = wrapper1.forward(&InnerExample1::DoSomething2, false);
模板
类包装器{
私人:
内在的;
公众:
模板

包装器(Args&&…Args):内部(std::forward

重写
操作符->()
怎么样?事实上,如果
包装器
像指针一样工作(语义上),那么肯定是一个解决方案是可以接受的。我必须编辑我的帖子——我试图省略细节以保持简单,但我想我遗漏了太多。我需要包装器类能够为每个调用插入一些额外的逻辑。实际上这非常有趣!我在这里看到的唯一一件事是
函数中的代码似乎假定了该函数如果std::mem_fun只支持一个参数包就可以了。另外,我希望包装器能够自己进行绑定,因此这需要包装器知道每个函数的返回类型/参数类型。STL只提供函数对象,包装成员函数不带参数或带参数一个参数,但您可以定义一个包含所有参数的结构,尽管它不是很优雅。如果您想自动计算返回/参数类型,您可以为此编写自己的类模板,或者使用boost,这很可能提供了某种功能。我实际上需要在包装类本身中插入一些逻辑不过,这将为每个调用的方法做一些工作。如果您需要更改方法的行为,则无法简单地对其进行过度隐藏或使用委派。您的意思是对任何调用的方法做相同的工作(例如,写入日志文件)?这被称为@c-smile在CRTP上读取,它看起来会给我ctor和dtor的挂钩,但不是每个单独的方法?@c-smile,而代码是编写的(在版本之前)当然类似于CRTP,如果我没有弄错的话,这不是一个例子。对于OP:Edited的答案。正如OP在回答下面提出相同问题的答案时所说的,问题是他们实际上希望
包装器
正确地代理包装类方法,以便他们可以在操作之前/之后注入额外的在方法调用中插入一个函数。
class Wrapped { 
public: 
    void DoSomething(); 
}; 

template<class T>  
class Wrapper { 
public: 
    T * operator->() { 
        return &t; 
    } 

private: 
    T t; 
}; 

int main() { 
    Wrapper<Wrapped> w; 
    w->DoSomething(); 
} 
template<typename Inner>
class Wrapper {
 private:
  Inner inner;
 public:

  template<typename ...Args>
  Wrapper(Args&&... args) : inner(std::forward<Args>(args)...) { }

  template<typename ...Args, typename R>
  R forward( R (Inner::* function)(Args...), Args &&...args) {
    return (inner.*function)(std::forward<Args>(args)...);
  }
};


Wrapper<InnerExample1> wrapper1(1, true);
wrapper1.forward(&InnerExample1::DoSomething1, 42);
bool result = wrapper1.forward(&InnerExample1::DoSomething2, false);