加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

指向C中的函数对象

发布时间:2020-12-16 10:30:40 所属栏目:百科 来源:网络整理
导读:我想将一个函数对象传递给一个类,该类将使用函数对象在类中做一些工作. 但问题是,我不会传入函数对象.所以我想,在类中定义一个void *指针,这个指针将用传入的函数对象初始化. 代码如下: class A { public: //... void doSomeJob(int x) { (*functor)(x); //
我想将一个函数对象传递给一个类,该类将使用函数对象在类中做一些工作.

但问题是,我不会传入函数对象.所以我想,在类中定义一个void *指针,这个指针将用传入的函数对象初始化.

代码如下:

class A 
{
    public:
        //...
        void doSomeJob(int x)
        {
            (*functor)(x); //use the function object to process data x
        }

    private:
        //...
        void *functor; //function object's pointer will be assigned to this pointer
};

但代码不起作用.我想,不能用那种方式使用void * functor.

我知道我可以使用模板类来完成这项工作,但我的问题是,我仍然可以使用指向函数对象的指针来完成工作吗?

PS

为了使我的问题更清楚,可能有几个函数对象因处理数据而彼此不同,我不会传递什么函数对象,但我知道每个函数对象都将采用一个int参数.

正如一些答案所说,我可以通过函数指针完成工作,但是函数对象比函数指针有更多的实用工具,比如状态,这就是我要用的东西.

解决方法

如果呼叫机构的类型未存储在呼叫机构可访问的某个位置,则无法在呼叫站点调用未知类型的功能对象.

有两种选择:

如果你可以使用C 11或boost,你可以使用std :: function resp.提振::函数:

class A
{
public:
  // ...
  void doSomeJob(int x)
  {
    functor(x);
  }
private:
  std::function<void(int)> functor; // or boost::function when using boost
};

这里的类型(以隐式形式)存储在函数模板的机制中.

否则,如果您可以要求传递的所有函数对象都具有从特定基类派生的类类型,则可以创建抽象基类:

struct AbstractFunctor
{
  virtual void operator()(int) = 0;
};

class A
{
public:
  // ...
  void doSomeJob(int x)
  {
    (*functor)(x);
  }
private:
  AbstractFunctor* functor; // or boost::function when using boost
};

这里的类型存储在函数对象的虚拟表中.

如果你真的不能使用boost,你也可以自己编写类似的解决方案.关键词是“类型擦除”,它基本上通过动态生成来自已知基类的派生对象(如我的第二个解决方案),它知道对象的类型并可以调用它.它可能大致如下(未经测试的代码):

class int_function
{
private:
  struct abstract_forward
  {
    virtual void call(int) = 0;
    virtual abstract_forward clone() const = 0;
    virtual ~abstract_forward() {}
  };
  template<typename Functor> struct forward: abstract_forward
  {
    forward(Functor f): func(f) {}
    void call(int i) { func(i); }
    abstract_forward clone() const { return new forward<Functor>(func); }
    Functor func;
  };
public:
  template<typename Functor> int_function(Functor f)
  {
    forwarder = new forward<Functor>(f);
  }
  int_function(int_function const& other)
  {
    forwarder = other.forwarder->clone();
  }
  int_function& operator=(int_function const& other)
  {
    abstract_forward* newfwd = other.forwarder->clone();
    delete forwarder;
    forwarder = newfwd;
  }
  ~int_function()
  {
    delete forwarder}
  }
  void operator()(int i)
  {
    forwarder->call(i);
  }
private:
  abstract_forward* forwarder;
};

class A
{
public:
  void doSomeJob(int x)
  {
    functor(x);
  }
private:
  int_function functor;
};

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读