指向 class 方法的多个指针

Multiple pointers to class methods

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

有点像 here,但有很小的差异,也可能没有。其他各种方法没有重载。
示例:

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

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

编辑:

想法是 OtherClass 是一个线程(不是标准的 c++ 线程)。其他 classes(Derived1, derived2...) 的一些代码 - 没有强制要求有一个共同的基础 class - 因此只有在这个线程结束它之后才能 运行 运行。 我希望看看我是否可以添加任何名称的方法。 作为线程也与此无关。它可以是一个简单的 class,当它结束其方法时,它 运行 是来自其他 classes 的一些代码。

我假设这些函数也是 return 相同的类型(我在这个例子中使用了 void)。

你没有说这些函数是否覆盖了在 base 中声明的虚函数——你提到它们不是重载,但如果它们不是覆盖,那么 base 的存在在这里并没有真正的帮助。

如果它们确实存在于 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)();
       }
    }
};

调用示例[​​=12=]

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

如果另一方面函数不覆盖 base 中的虚函数,那么我有另一个涉及包装器的解决方案 class,如果上述方法不起作用,我可以 post你.

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

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

// https://github.com/KubaO/Whosebugn/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);
}