如何使用函数指针调用对象的方法?

时间:2017-06-01 01:40:41

标签: c++ member-function-pointers visual-studio-2017

我想打电话给几种课程方法' A'和' B'来自班级'来电者'。我需要使用函数指针,因为我想调用不同的方法。

我的方法被调用,但是当我尝试从中访问成员变量时,我的程序崩溃了(' program.exe已停止工作')。

怎么会发生这种情况?

#include <iostream>

using namespace std;


template <class T>
class Caller
{
    typedef void (T::*myFunc)(int);
    public: 
        Caller(T* obj, myFunc fp)
        {
            f = fp;
        }
        void invoke(int foobar)
        {
            (o->*f)(foobar);
        }
    private:
        myFunc f;
        T* o;
};

class A
{
    public:
        A() : n(0) {}
        void foo(int bar)
        {
            cout << "A::foo called (bar = " << bar << ", n = " << n << ")" << endl; // the crash occurs here, and 'this' equals 0 at this point
        }
        void setNum(int num)
        {
            n = num;
        }
    private:
        int n;
};

class B
{
    public:
        B() : n(0) {}
        void fooo(int bar)
        {
            cout << "B::fooo called (bar = " << bar << ", n = " << n << ")" << endl; // same here if I call B::fooo first
        }
        void setNum(int num)
        {
            n = num;
        }
    private:
        int n;
};

int main()
{
    A myA;
    B myB;

    myA.setNum(128);
    myB.setNum(256);

    Caller<A> cA(&myA, &A::foo);
    Caller<B> cB(&myB, &B::fooo);

    cA.invoke(10);
    cB.invoke(20);

    return 0;
}

提前谢谢。

编辑:我使用VS2017,我可以构建我的程序而不会出现任何编译器错误。

1 个答案:

答案 0 :(得分:1)

  

我的方法被调用,但当我尝试从中访问成员变量时,我的程序崩溃......

因为您忘记在obj中将o指针传递给Caller指针:

template <class T>
class Caller
{
    typedef void (T::*myFunc)(int);
public:
    Caller(T* obj, myFunc fp)
    {
        o = obj;  // << == you need this!
        f = fp;
    }
    void invoke(int foobar)
    {
        (o->*f)(foobar);
    }
private:
    myFunc f;
    T* o;
};

另外,一般来说,使用member initializer lists更好:

Caller::Caller(T* obj, myFunc fp) : o(obj), f(fp)
{
}