C++回拨系统。指向成员函数的指针

发布于 2024-09-28 07:02:46 字数 700 浏览 4 评论 0原文

我试图通过传递指向成员函数的指针来创建回调,但遇到了所有类型的问题。

我怎样才能着手实施这样的事情

template<class T> class A{

   void (T::*callBackFunction)(int);

   public:
       void addCallBack(void (T::*callBackFunction)(int)){
            void (T::*callBackFunction)(int) = &callBackFunction;
       }

       void performCallBack(){ //I want this to activate the specified function in class B
            callBackFunction(3);
       }
};





Class B{

   A<B> a1;
   A<B> a2;

   B(){
       a1.addCallBack(&a1CallBack);
       a2.addCallBack(&a2CallBack);
   }

   void a1CallBack(int i){
       // do stuff
   }

   void a2CallBack(int i){
       // do stuff
   }
};

Im trying to create a call back by passing a pointer to member functions but am running into all types of issues.

How can i go about implementing such a thing

template<class T> class A{

   void (T::*callBackFunction)(int);

   public:
       void addCallBack(void (T::*callBackFunction)(int)){
            void (T::*callBackFunction)(int) = &callBackFunction;
       }

       void performCallBack(){ //I want this to activate the specified function in class B
            callBackFunction(3);
       }
};





Class B{

   A<B> a1;
   A<B> a2;

   B(){
       a1.addCallBack(&a1CallBack);
       a2.addCallBack(&a2CallBack);
   }

   void a1CallBack(int i){
       // do stuff
   }

   void a2CallBack(int i){
       // do stuff
   }
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吲‖鸣 2024-10-05 07:02:46

你可以做这样的事情。虚拟基类BaseCB允许B完全不知道C的类型,但仍然调用回调。

class BaseCB{
public:
  virtual void operator()(int x)=0;
};

template<class ClassT>
class CCallback : public BaseCB {
public:
  typedef void(ClassT::* FuncT)(int);
  FuncT _fn;
  ClassT* _c;
  CCallback(ClassT* c, FuncT fn):_fn(fn),_c(c){}
  void operator()(int x){
    return (_c->*_fn)(x);
  }
};

class B {
public:
  BaseCB* a;
  void invokecb(int n){
    (*a)(n);
  }
};

class C {
  B b;
public:
  C(){
    b.a = new CCallback<C>(this,&C::cb);
    b.invokecb(3);
  };
  void cb(int n)
  {
    cout << n;
  }
};

C c; // create an instance of c and test the cb mechanism

You could do something like this. The virtual base class BaseCB allows B to be totally unaware of the type of C but still invoke the callback.

class BaseCB{
public:
  virtual void operator()(int x)=0;
};

template<class ClassT>
class CCallback : public BaseCB {
public:
  typedef void(ClassT::* FuncT)(int);
  FuncT _fn;
  ClassT* _c;
  CCallback(ClassT* c, FuncT fn):_fn(fn),_c(c){}
  void operator()(int x){
    return (_c->*_fn)(x);
  }
};

class B {
public:
  BaseCB* a;
  void invokecb(int n){
    (*a)(n);
  }
};

class C {
  B b;
public:
  C(){
    b.a = new CCallback<C>(this,&C::cb);
    b.invokecb(3);
  };
  void cb(int n)
  {
    cout << n;
  }
};

C c; // create an instance of c and test the cb mechanism
柠檬心 2024-10-05 07:02:46

指向成员函数的指针需要一个指向实例的指针作为其第一个参数。 阅读本文。执行此操作的一般方法是让回调函数采用一个额外的参数(通常是 void *),该参数可以代表回调处理程序的额外信息或上下文。这可能是指向回调将被委托给的对象的指针。

Pointers to member function require a pointer to an instance as their first parameter. Read this. The general way to do this is to have the callback function take an extra parameter (usually a void *) that can represent extra information or context for the callback handler. This could be the pointer to an object to which the callback would be delegated.

旧竹 2024-10-05 07:02:46

您需要对要调用其方法的对象的引用(或指针)。

我建议创建一个模板基类(模板参数是函数返回值和参数)和一个模板派生类(所有基模板参数,加上对象类型)。派生类保存对象的引用和成员函数的指针。

编辑:

也许是这样的(未经测试):

template < typename R, typename T1 >
class CbBase
{
  public:
    virtual ~CbBase(){}
    virtual R call( T1 t1 ) = 0;
};

template < typename O, typename R, typename T1 >
class MemFunPtrCb : public CbBase< R, T1 >
{
  public:
    MemFunPtrCb( O &obj_, R (O::*memFcPtr_)( T1 t1 ) ) :
      obj( obj_ ),
      memFcPtr( memFcPtr_ ),
    {
    }

    virtual R call( T1 t1 )
    {
        obj.memFcPtr( t1 );
    }

  private:
    O &obj;
    R (O::*memFcPtr)( T1 t1 );
};

这个例子丢失了:

  • 一个创建MemFuncPtrCb对象的函数,这个函数需要引用该对象和成员函数,并将shared_ptr返回到适当的基类< /p>

  • typedefs

You need the reference (or a pointer) to the object on which you want to call the method.

I would suggest to create a template base class (template parameters are function return value and parameters), and a template derived class (all base template parameters, plus the object type). The derived class holds the reference to the object and the pointer to the member function.

EDIT:

Maybe something like this (not tested) :

template < typename R, typename T1 >
class CbBase
{
  public:
    virtual ~CbBase(){}
    virtual R call( T1 t1 ) = 0;
};

template < typename O, typename R, typename T1 >
class MemFunPtrCb : public CbBase< R, T1 >
{
  public:
    MemFunPtrCb( O &obj_, R (O::*memFcPtr_)( T1 t1 ) ) :
      obj( obj_ ),
      memFcPtr( memFcPtr_ ),
    {
    }

    virtual R call( T1 t1 )
    {
        obj.memFcPtr( t1 );
    }

  private:
    O &obj;
    R (O::*memFcPtr)( T1 t1 );
};

This example is missing :

  • a function to create MemFuncPtrCb object, this function needs to take a reference to the object, and member function, and return shared_ptr to the appropriate base class

  • typedefs

浮生面具三千个 2024-10-05 07:02:46

如果你真正想要的是一个以int为参数并返回void的回调函数,你可以使用boost::function。

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

struct A
{
   typedef boost::function1<int, void> func_type;
   func_type func;

   explicit A( func_type func_ ) :
      func( func_ )
   {
   }

   void call( int x )
   {
       func(x);
   }
};

struct B
{
   int myVal;
   explicit B(int val ) : myVal( val ) {}

   void mycall(int x)
    {
       std::cout << (myVal + x) << std::endl;
    }
};

int main()
{
   B b(5);
   A a( boost::bind( &B::mycall, b, _1 ) );
   a.call( 3 );
}

运气好的话,它会打印出 8。

If what you really want is a callback function that takes int as a parameter and returns void, you can use boost::function.

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

struct A
{
   typedef boost::function1<int, void> func_type;
   func_type func;

   explicit A( func_type func_ ) :
      func( func_ )
   {
   }

   void call( int x )
   {
       func(x);
   }
};

struct B
{
   int myVal;
   explicit B(int val ) : myVal( val ) {}

   void mycall(int x)
    {
       std::cout << (myVal + x) << std::endl;
    }
};

int main()
{
   B b(5);
   A a( boost::bind( &B::mycall, b, _1 ) );
   a.call( 3 );
}

and with any luck it will print 8.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文