首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++::成员函数数组

C++::成员函数数组
EN

Stack Overflow用户
提问于 2015-09-17 10:09:39
回答 2查看 1.9K关注 0票数 0

我想存储不同类的成员函数数组。这里只重复一遍:

要求:

  • TypeOf
  • 包含函数的类的实例
  • AddressOf成员函数
  • 成员函数参数

我能储存的东西:

  • 包含函数的类的实例
  • AddressOf成员函数。
  • 成员函数参数

通常,您不需要存储类类型,因为您可以创建指向Class类型的数组指针。我不能这样做的原因是因为我接受的类类型是未知的和不同的。该类将用于许多类类型未知的不同项目中。

我需要将不同类型的类存储到Array/List中,在这种情况下,我只需将类的地址存储到数组指针中。

My Problem:当我要调用成员函数时,我需要将类地址转换为Class类型,但我不知道要转换到什么类型。

示例代码(未测试-编写得很快):

代码语言:javascript
复制
class A
{
    public:
        void test1(int i);
};

class B
{
    public:
        void test2(char c);
};

class Container
{
    long* objects;
    long* funcs;
    int index;

    public:

        Container()
        {
            objects = new long[5];
            funcs = new long[5];
            index = 0;
        }

        template <class C, typename Types ...>
        void Add(C *obj, void (C::*func)(Types ...))
        {
            objects[index++] = (long)obj;
            funcs[index++] = (long)func;
        }

        typename <Types ...>
        void Call(int inx, Types ... values)
        {
            void (*func)(Types ...) = (void (*)(Types ...))funcs[inx];

            // This is where I've got trouble. I don't store the Class 
            // types, so I don't know what pointer Class type to cast 
            // the Class Instance address to.
            (((*???)objects[inx])->*func)(values ...);
        }
};

提前谢谢。如果有任何漏洞或问题,请提前问。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-17 10:26:22

你能把这个限制在成员函数的签名上吗?如果是这样,则可以存储绑定函数,而不是单独存储指向对象和成员函数的指针。

代码语言:javascript
复制
template<typename... Args>
class Container {
public:
    typedef std::function<void (Args...)> F;

    template <class C>
    void Add(C* obj, void (C::*func)(Args ...))
    {
        functions.push_back( [=](Args... args) {(obj->*func)(args...);} );
    }

    void call(size_t i, Args... args)
    {
        functions[i](args...);
    }

private:
    std::vector<F> functions;
};
票数 3
EN

Stack Overflow用户

发布于 2015-09-17 14:18:58

IMHO,您的帖子看起来可能是一个有趣的多态编程挑战,但是添加了一个要求,“没有多态性”.在这种情况下,你要学习更困难的方法。

我要谈的是你所说的问题:

当我要调用成员函数时,我需要将类地址转换为Class类型,但我不知道要转换到什么类型。

过去被称为Thunk (当我第一次遇到它时)。在最近的一次(相对的)搜索中,我还没有找到这个名字下的这个想法(也确实发现了其他几种叫做“一击”的东西)。对我曾经读过的名字的解释是这样的,因为“它封装了我已经说过的东西”。

注意,有了雷击,就不需要强制转换了(因为你已经拒绝了)

使用thunk作为容器中的对象。

哦,既然您标记了这个C++,那么您实际上应该使用std::vector < PVThunk_t >。

代码语言:javascript
复制
  // ////////////////////////////////////////////////////////////////////
  // Pure Virtual Thunk_t: an abstract base class
  class PVThunk_t
  {
  public:
     virtual ~PVThunk_t(){}

     virtual void operator()(void* v) = 0;
     virtual void exec      (void* v) = 0;
  };
  // pure-virtual requires derived objects to implement both methods

// ///////////////////////////////////////////////////////////////////////
// template class - make it easy to create thunk for any class T
template <class T>
class Thunk_t : PVThunk_t
{
public:
   // constructor - takes pointer to an object and pointer to a member and stores
   // them in two private variables
   Thunk_t( T*    anInstance,        // pointer to an instance of class T
            void* (T::*aMethod)()) : // pointer to a  method   of class T, no parameter, returns void
      m_instance (anInstance),
      m_method   (aMethod)
      {
         assert  (m_instance);
         asssert (m_method);
      }

   Thunk_t( T*  anInstance,        // pointer to an instance of class T
            T*  (T::*aMethod)()) :  // pointer to a  method   of class T, no parameter, returns T*
      m_instance (anInstance),
      m_method   (aMethod)
      {
         assert  (m_instance);
         asssert (m_method);
      }

   virtual ~Thunk_t() { }

   // override operator "()"
   virtual void* operator()(void* v) { return((*m_instance.*m_method)(v)); }

   // override function "exec"
   virtual void* exec(void* v) { return((*m_instance.*m_method)(v)); }

private:
   T*        m_instance;         // pointer to object of T
   void (T::*m_method)(void*);   // pointer to method attribute of T with void* param

}; // template <class T>  class Thunk_t : public PVThunk_t

注意声明m_instance和m_method指针的正确机制。

如果需要使用具有可变参数数的方法,我建议传递一个struct指针(对Thunk进行适当的调整或添加)。单个方法参数始终是指向结构的指针,然后调用的方法可以推断其类型或内容。

我已经很久没有使用这个Thunk了,因为多态在各个方面都是优越的。但是Thunk仍然在编译,所以它可能会起作用。

更新-注意到虚拟方法不匹配。固定

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32627769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档