多个指向类方法的指针

时间:2016-08-02 10:50:24

标签: c++ function-pointers member-function-pointers

我有一个类,它应该包含指向各种类的方法的指针并通过它调用它们。

here这样的东西,但有一个小的 - 或者可能没有区别。那些各种其他方法都不会超载 示例:

Derived1 d1;    
OtherClass* handlerInst = new OtherClass();
handlerInst->Add( &d1, &(Derived1::method1) );

Add(...)中我想传递从base派生的类类型的成员方法 这有可能吗?

编辑:

这个想法是OtherClass是一个线程(不是标准的c ++线程)。其他类的一些代码(Derived1,derived2 ...) - 不必具有公共基类 - 因此必须在此线程结束其运行后才能运行。 我希望看看我是否可以添加任何名称的方法。 也是一个线程与此无关。它可以是一个简单的类,当它结束它的方法时,它会从其他类运行一些代码。

2 个答案:

答案 0 :(得分:1)

我假设这些函数也返回相同的类型(在这个例子中,我已经使用了void)。

你不能说这些函数是否覆盖了在base中声明的虚函数 - 你提到它们不是重载,但是如果它们没有覆盖那么base的存在对这里没有帮助。 / p>

如果它们确实存在于base中,那么您可以尝试以下操作:

#include <vector>
class OtherClass 
{ 
    using FunctionPtrType = void(Base::*)();
    std::vector<std::pair<Base*, FunctionPtrType>> m_Collection;

   public:


   void Add(Base* object, FunctionPtrType pMemberFunction)
   {
       m_Collection.emplace_back(object, pMemberFunction);
    }

   void CallAll()
   {
       for(auto item : m_Collection)
       {
           (item.first->*item.second)();
       }
    }
};

调用示例

Derived d1;
OtherClass holder;
holder.Add(&d1, &Base::Func);
holder.CallAll()

另一方面,如果函数不覆盖base中的虚函数,那么我有另一个涉及包装类的解决方案,如果以上内容对你不起作用我可以发布。

答案 1 :(得分:0)

您可以存储绑定到其实例的成员函数,并使用std::is_base_of检查它们的类型是否正确。

在下面的示例中,每个方法都存储了两次,因此它们也会被调用两次。

// https://github.com/KubaO/stackoverflown/tree/master/questions/method-ptr-list-38718402
#include <cassert>
#include <vector>
#include <functional>
#include <type_traits>

struct Base {};
struct Derived : Base {
   int counter = 0;
   void method1() { counter += 10; }
   void method2() { counter += 100; }
};

template <typename B>
class HandlerList {
   using fun = std::function<void()>;
   std::vector<fun> m_handlers;
public:
   template <typename T,
             typename = typename std::enable_if<std::is_base_of<B, T>::value>::type>
   void add(T* instance, void(T::* member)()) {
      m_handlers.push_back(std::bind(member, instance));
   }
   template <typename T,
             typename = typename std::enable_if<std::is_base_of<B, T>::value>::type>
   void add(T* instance, std::initializer_list<void(T::*)()> members) {
      for (auto & member : members)
         add(instance, member);
   }
   void call() {
      for (auto const & handler : m_handlers)
         handler();
   }
};

int main()
{
   struct NotDerived { void foo() {} } nd;
   Derived d;
   HandlerList<Base> h;
   h.add(&d, &Derived::method1);
   h.add(&d, &Derived::method2);
   h.add(&d, { &Derived::method1, &Derived::method2 });
#if 0
   h.add(&nd, &NotDerived::foo); // this will fail to compile
#endif
   h.call();
   assert(d.counter == 220);
}