Avinash
Avinash

Reputation: 13257

Generic Function pointer to the class member function

How can I have generic function pointer. Consider following class.

#ifndef PERSON_HPP_
#define PERSON_HPP_

#include <string>

class Person {
public:
  Person() {
  }
  void SetName(std::string person_name) {
    m_name = person_name;
  }
  void setDept(std::string dept_name) {
    m_dept = dept_name;
  }
  void setAge(int person_age ) {
    m_age = person_age;
  }
  std::string getName() {
    return m_name;
  }
  std::string getDept() {
    return m_dept;
  }
  int getAge() {
    return m_age;
  }
private:
  std::string m_name;
  std::string m_dept;
  int m_age;
};

#endif

I want to store the function pointers in a std::vector for setName, setDept , constructor and so on ...

For normal function I could achieve this using following

#include <vector>


int mult(int a) { 
  return 2*a; 
}

int main()
{
    int b;

    std::vector<void *(*)(void *)> v;
    v.push_back((void *(*)(void *))mult);
    b = ((int (*)(int)) v[0])(2);        // The value of b is 2.

    return 0;
}

No Boost allowed in my case.

Upvotes: 0

Views: 1897

Answers (3)

If you really need to cast the member pointers to a common type (like void*), you can do:

template <typename T>
void* castToVoidStar(T x) {
  return *reinterpret_cast<void**>(&x);
}

void *afterCast = castToVoidStar(&Person::getName)

However, I do not believe it is wise to do so. C++ has type safety for a reason.

Upvotes: 0

iammilind
iammilind

Reputation: 70000

It seems that you want to avoid the re-writing the getter/setter method, which typically have similar code inside.
However, it's a bad idea to use function pointer for such task because it reduces readability, adds complexity and doesn't allow the compiler to do the optimizations related to inlining.

If you want to automate the code generation for using getter/setter then use editor which has facility to generate getter/setter such as eclipse or you can resort to macros in this case:

#define SETTER(TYPE,FIELD) \
  set##FIELD (const TYPE FIELD) \
  { \
    this->m_##FIELD = FIELD; \
  }
#define GETTER(FIELD) \
  get##FIELD () const \
  { \
    return this->m_##FIELD; \
  }

And use it as,

class Person {
public:
  Person() {
  }
  void SETTER(std::string, name);
  void SETTER(std::string, dept);
  void SETTER(int, age);

  int GETTER(name);
  int GETTER(dept);
  int GETTER(age);

private:
  std::string m_name;
  std::string m_dept;
  int m_age;
};

#undef SETTER
#undef GETTER

Upvotes: 1

Kirill Kobelev
Kirill Kobelev

Reputation: 10557

You can write:

// Pointer to member function as a data type. 
typedef void (Person::*MethodPtr)(std::string); 
std::vector<MethodPtr> v;

Pointers to members are not any way different from any other data types. Only it should be used as binary operator:

Person *bad_guy = ...;
bad_guy->*v[4]("abcd");

Upvotes: 1

Related Questions