C ++. Указатели на метод класса - PullRequest
9 голосов
/ 23 июля 2010

Есть класс

class A {
public:
    A() {};

private:
    void func1(int) {};
    void func2(int) {};


};

Я хочу добавить указатель на функцию, который будет установлен в конструкторе и указывает на func1 или func2.

Таким образом, я могу вызвать этот указатель (как член класса) из каждой процедуры класса и установить этот указатель в конструкторе.

Как я могу это сделать?

Ответы [ 7 ]

8 голосов
/ 23 июля 2010
class A {
public:
    A(bool b) : func_ptr_(b ? &A::func1 : &A::func2) {};

    void func(int i) {this->*func_ptr(i);}

private:
    typedef void (A::*func_ptr_t_)();
    func_ptr_t_ func_ptr_;

    void func1(int) {};
    void func2(int) {};
};

Тем не менее, может стать лучшим способом сделать то, что вы хотите с этим сделать.

5 голосов
/ 23 июля 2010

Добавить переменную-член

void (A::*ptr)();

установить его в конструкторе

ptr=&A::func1;

(или используйте список инициализаторов) и вызовите его в методах A:

(this->*ptr)();
2 голосов
/ 23 июля 2010

Я скомпилировал и запустил этот код.Различные члены должны быть открытыми, чтобы вы могли передать их в конструктор.В противном случае, здесь вы идете.

Тем не менее, я согласен с другими авторами, что это почти определенно плохая вещь.;) Просто сделайте invoke pure virtual, а затем создайте два подкласса A, каждый из которых переопределит invoke ().

2 голосов
/ 23 июля 2010

См. boost :: function , чтобы узнать, как обрабатывать указатели на функции и члены класса более понятным образом OO / C ++.

Например (из документации):

struct X 
{
  int foo(int);
};

boost::function<int (X*, int)> f;

f = &X::foo;

X x;
f(&x, 5);
1 голос
/ 23 июля 2010

Я предлагаю вам использовать функтор (или объект функции), а не указатель на функцию, поскольку первый безопаснее, а указатель на функцию может быть затруднительным или неудобным для передачи состояния в или из функции обратного вызова

Функтор - это, по сути, повторная реализация operator () класса A, для очень подробного описания, пожалуйста, обратитесь к Википедии: http://en.wikipedia.org/wiki/Function_object

Код должен быть примерно таким:

class A {
public:
    A() {};
    void operator()(int function_index, int parameter) {
    if(function_index == 1)
        func1(parameter);
    else if(function_index == 2)
        func2(parameter);
    else
        { //do your other handling operation
        }
  }


private:
    void func1( int ) {};
    void func2( int) {};
};

Используя этот класс:

A a;
a(1, 123); //calling func1
a(2, 321); //calling func2
0 голосов
/ 23 июля 2010

Почему вы думаете, что это плохо? Мне просто нужен один указатель на функцию, и я не хочу создавать два подкласса для этого. Так почему же так плохо?

0 голосов
/ 23 июля 2010

Некоторые примеры ...

class A; // forward declaration
typedef void (A::*func_type)(int);

class A { 
public:
  A() {
    func_ptr = &A::func1;
  }

  void test_call(int a) {
    (this->*func_ptr)(a);
  }

private:
  func_type func_ptr;

  void func1(int) {}
  void func2(int) {}
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...