Search code examples
c++vectorfunction-pointers

Vector of pointer to member functions


I'm trying to write a program which creates a class that contains vector of pointers to member functions, with add() and remove() member functions. The code I wrote is -

#include <iostream>
#include <vector>
using namespace std;

typedef void(*classFuncPtr)();

class FunctionVectors
{
private:
   vector<classFuncPtr> FunctionPointerVector;
 public:
   FunctionVectors(){}
   void add(classFuncPtr funcPtr);
   void remove(int index);
   void run();
   void a(){cout<<"a: Why are you calling me?"<<endl;}
 };
 
 void FunctionVectors::add(classFuncPtr funcPtr)
 {
   FunctionPointerVector.push_back(funcPtr);
 }
 
 void FunctionVectors::remove(int index)
 {
   FunctionPointerVector.erase(FunctionPointerVector.begin() + index);
 }
 
int main()
{
   FunctionVectors f;
   classFuncPtr fv = &(classFuncPtr)FunctionVectors::a;  // error here
  
   f.add(fv);
   f.run();
  
   return 0;
}

But, it is showing error in line# 32 -

error C2440: 'type cast' : cannot convert from 'void (__thiscall FunctionVectors::* )(void)' to 'classFuncPtr'  

Please, tell me how should I modify it to work properly.


Solution

  • typedef void(*classFuncPtr)();
    

    This is not a pointer to method, but a pointer to function. Method differs from function, because it's being called in a context: requires this to work correctly.

    Keep in mind, that in C++ you are only able to create vector of pointers to a method of specific class. So you won't be able to keep pointers to two methods of different classes in that vector.

    The solution - as suggested in comments - is to use std::function or boost::function and possibly C++11 lambdas, because they provide a lot more flexibility than simple pointer-to-members.

    If you want to implement an event mechanism, consider also using functors instead of methods:

    1. Create base class for event handler:

      class MyEventHandler
      {
      public:
          virtual void operator()(void * sender, int data) = 0;
      }
      
    2. Create simple vector of these:

      std::vector<MyEventHandler *> MyEvent;
      
    3. Create specific handlers in your classes:

      class MyClass
      {
      private:
          class SpecificEventHandler : MyEventHandler
          {
          public:
              void operator()(void * sender, int data)
              {
                  std::cout << "Event handled!";
              }
          }
      
      public:
          SpecificEventHandler Handler;
      
          MyClass()
          {
          }
      }
      
    4. Hook the handler to your event:

      MyEvent.push_back(&(myClassInstance.Handler));
      

    Code written from memory, may not compile, but you should get the idea.