C++. Указатели метода класса

Существует класс

class A {
public:
    A() {};

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


};

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

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

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

9
задан Wolf 16 September 2015 в 08:49
поделиться

7 ответов

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) {};
};

Учитывая это, полиморфизм может быть лучшим способом сделать все, что вы хотите сделать с этим.

8
ответ дан 4 December 2019 в 11:39
поделиться

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

void (A::*ptr)();

, установите ее в конструкторе

ptr=&A::func1;

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

(this->*ptr)();
5
ответ дан 4 December 2019 в 11:39
поделиться

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

Functor - это, по сути, повторная реализация operator() класса A, для очень подробного описания, пожалуйста, обратитесь к Wikipedia: 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
1
ответ дан 4 December 2019 в 11:39
поделиться

Пример ...

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) {}
};
0
ответ дан 4 December 2019 в 11:39
поделиться

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

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

struct X 
{
  int foo(int);
};

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

f = &X::foo;

X x;
f(&x, 5);
2
ответ дан 4 December 2019 в 11:39
поделиться

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

0
ответ дан 4 December 2019 в 11:39
поделиться

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

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

#include <iostream>
using namespace std;

class A;
typedef void(A::*MyFunc)(int) ;

class A { 
    public: 

        A() {}
        A(MyFunc fp): fp(fp) {}

        void invoke(int a)
        {
            (this->*fp)(a);
        }

        void func1(int a) { cout << "func1 " << a << endl; }
        void func2(int a) { cout << "func2 " << a << endl; }
    private: 

        MyFunc fp;
};

int main()
{
    A* a = new A( & A::func1 );
    a->invoke(5);
    A* b = new A( & A::func2 );
    b->invoke(6);
}
2
ответ дан 4 December 2019 в 11:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: