类变量中的函数指针

时间:2019-04-05 12:48:30

标签: c++

是否可以在这个或另一个类的变量中保存指向类方法的指针?如果这不可能,我也想知道为什么。

可以在类外部创建变量,并为其分配类方法。也调用此方法。但是,由于将此变量作为类字段包含在内,因此该示例停止工作。

也可以使用this指针在类本身中调用此方法。为什么这样工作?

不起作用的示例。所需结果

#include <iostream>

using namespace std;


class B {
public:
    typedef void (B::*function_type)(void);
    B::function_type _func;

    B() {
        cout << "B" << endl;
    }
    void foo(){
        cout << "B foo" << endl;
    }
};

int main()
{
    B b;
    b._func = &B::foo;

    (b.*_func)();
}

在班级内部打电话

#include <iostream>
#include <functional>

using namespace std;


class B {
public:
    typedef void (B::*function_type)(void);
    B::function_type _func;

    B() {
        cout << "B" << endl;
    }
    void foo(){
        cout << "B foo" << endl;
    }

    void run() {
        (this->*_func)();
    }
};

int main()
{
    B b;
    b._func = &B::foo;
    b.run();
}

我想保存一个类方法并通过一个对象调用它。

3 个答案:

答案 0 :(得分:3)

调用您的_func指针涉及两个对象。一个是应将函数应用于的对象,另一个是保存指针的对象。当您在成员函数中时,第一个隐含;它是内部this指针。因此(this->*_func)()调用当前对象上的数据成员_func。当您不在成员函数中时,必须提供两个对象:

(b.*b._func)();

左侧的b与第一个版本中的this->类似:它告诉编译器哪个对象也可以应用该函数。第二个b是保存指针的对象。

如果这完全令人困惑,请稍微改变一下情况。使用两个B对象并播放其中一个对象:

B b;
B b1;

(b.*b1.func)();
(b1.*b.func)();

答案 1 :(得分:1)

有可能。语法有点吓人:

(b.*(b._func))();

为什么会这样?好吧,首先您需要引用对象_func的数据成员b。那就是b._func。接下来,您需要将该数据成员称为数据函数指针,该指针是(b.*(..))()部分。

我建议通过创建一个执行疯狂调用语法的方法来简化调用方:

class B {
    // ...
    void call_me()
    {
        (this->*(_func))();
    }

};

b.call_me();

一些改进的提示:

使用using代替typedef

using function_type = void (B::*)(void);

您不需要B::function_type。仅function_type就足够了,因为您在类的范围之内。

答案 2 :(得分:0)

您的第一个示例(不起作用的示例)仅在您引用静态函数时才能工作,因为可以在没有调用对象实例的情况下调用静态方法,而该实例实例与您的情况相对应。 ( b。* (b._func))();

因此,您可以编写:

class B {

public:
    typedef void (*function_type)(void);
    function_type _func;

    B() { cout << "B" << endl;}
    static void foo(){ cout << "B foo" << endl; }
};

int main()
{
    B b;
    b._func = &B::foo;
    (b._func) ();
}