指向类成员函数的通用函数指针

时间:2012-10-31 08:17:01

标签: c++ function-pointers

我如何拥有通用函数指针。考虑下课。

#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

我想将函数指针存储在std::vector setNamesetDeptconstructor...

对于正常功能,我可以使用以下

来实现
#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;
}

我的案件中不允许Boost

3 个答案:

答案 0 :(得分:1)

你可以写:

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

指向成员的指针与任何其他数据类型没有任何不同。只有它应该用作二元运算符:

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

答案 1 :(得分:1)

您似乎希望避免重写getter/setter方法,该方法通常包含类似的代码。
但是,将函数指针用于此类任务是一个坏主意,因为它会降低可读性,增加复杂性并且不允许编译器执行与内联相关的优化。

如果你想使用getter/setter自动化代码生成,那么使用具有生成getter / setter的工具的编辑器,例如eclipse,或者你可以在这种情况下使用宏:

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

并将其用作,

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

答案 2 :(得分:0)

如果确实需要将成员指针强制转换为常见类型(如void *),则可以执行以下操作:

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

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

但是,我不认为这样做是明智的。出于某种原因,C ++具有类型安全性。