开发者

C++. Class method pointers

开发者 https://www.devze.com 2023-01-08 19:55 出处:网络
There is a class class A { public: A() {}; private: void func1(int) {}; void func2(in开发者_运维问答t) {};

There is a class

class A {
public:
    A() {};

private:
    void func1(int) {};
    void func2(in开发者_运维问答t) {};


};

I want to add a function pointer which will be set in constructor and points to func1 or func2.

So I can call this pointer (as class member) from every class procedure and set this pointer in constructor.

How can I do it?


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

That said, polymorphism might be a better way to do whatever you want to do with this.


Add a member variable

void (A::*ptr)();

set it in the constructor

ptr=&A::func1;

(or use the initializer list) and call it in methods of A:

(this->*ptr)();


I compiled and ran this code. The various members need to be public so you can pass them into the constructor. Otherwise, here you go.

However, I agree with other posters that this is almost definitely a bad thing to do. ;) Just make invoke pure virtual, and then make two subclasses of A which each override 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);
}


See boost::function for a way to handle function and class member pointers in a more OO/C++ manner.

For example (from the documentation) :

struct X 
{
  int foo(int);
};

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

f = &X::foo;

X x;
f(&x, 5);


I suggest you use functor(or function object), rather than function pointer, because the former is safer, and function pointer can be difficult or awkward to pass a state into or out of the callback function

A functor is basically a re-implementation of operator() of class A, for very detailed description please refer to Wikipedia: http://en.wikipedia.org/wiki/Function_object

The code should be something like this:

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

By using that class:

A a;
a(1, 123); //calling func1
a(2, 321); //calling func2


Why do you think it's a bad thing to do. I just need one function pointer and I don't want to create two subclasses for this. So why is it so bad?


Some example...

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

精彩评论

暂无评论...
验证码 换一张
取 消