当它是指向类功能的指针时,如何正确调用函数,但在该类外部

how to properly call a function when it is a pointer to a class function but is outside that class

本文关键字:调用 何正确 函数 外部 功能 指针      更新时间:2023-10-16

对不起,如果该标题措辞不佳...但是这是我想做的...

我有一个结构"屏幕",它的指针指向这些功能,这些功能是"测试"的成员...

typedef struct screen{
     ...
     bool (Test::*drawfunc)(b2World*, objectdata*, actorlist*, camera*);    
     ...
}
class Test{
     ...
     screen* tscreen;
     bool Test::draw(b2World* world, objectdata* objects, actorlist* al, camera* cam);
     ...
}

我在创建我的测试实例"测试"时分配了drawfunc指针...对我来说看起来很奇怪,我不完全理解它,但是它编译了...

Test::Test()
{
     ...
     tscreen->drawfunc=&Test::draw;
     ...
}

,但我不知道如何在我的主体中调用drawfunc函数...我是这样尝试的,并且会出现错误"错误c2064:enter term n term n term ten n tor to to toting 4参数"

int main (int acrgc, char** argv){
     ...
     Test* test = new Test();
     test->tscreen->drawfunc(test->m_world, test->objects, test->tscreen->al, test->tscreen->cam);
     ...
}

我知道呼叫不正确,我从未指定drawfunc的类"测试"的实例。..

...对于不可避免的"你为什么要这样做?"回复...或者如果没有办法调用该功能或其他方法...我真的只想能够为" drawfunc"分配不同的功能,我希望这些函数能够使用所有变量在实例"测试"中,我可以将其绘制到任何旧函数(bool( drawfunc)(b2world ,objectdata*,actorList*,camera*);),但需要是能够访问测试实例"测试"中的其他变量。所以...实际上,您这样做也很棒。谢谢。

您这样做:

(test ->* test->tscreen->drawfunc)(test->m_world, test->objects, test->tscreen->al, test->tscreen->cam);

通常,间接指针到成员涉及使用->*.*操作员。如果您有指向对象a和指针到会员b的指针,则您会说a ->* b。在您的情况下,对象的指针是test,您的指针到成员为test->tscreen->drawfunc。额外的括号是必需的,因为->*是二进制运算符,其优先级比"后缀函数"调用call oterator (),但是您想在调用它之前间接指针到会员。

最简单的方法是不直接使用函数指针并将其包裹在诸如std::function之类的函子中。对于成员函数,使用std::bind()将对象绑定到函子中:

struct foo
{
    void f()
    {
        std::cout << "f()!" << std::endl;
    }
};
int main()
{
    foo my_foo;
    auto f_wrapper = std::bind( &foo::f , my_foo );
    f(); 
}

f()!

这很容易将不同的功能传递给功能或其他功能。例如:

class a_class_which_does_complex_drawings
{
    void draw();
};
void a_global_function_which_draws_things();

template<typename DRAW_FUNCT>
void the_function_which_really_draws( DRAW_FUNCT drawing_method )
{
    drawing_method(); //Tah dah!
}
int main()
{ 
    typedef std::function<void()> drawing_callback_t;
    std::vector<drawing_callback_t> callbacks;
    a_class_which_does_complex_drawings mi_complex_drawer;

    callbacks.push_back( a_global_function_which_draws_things ); //Works
    callbacks.push_back( std::bind( &a_class_which_does_complex_drawings::draw ,
                                    my_complex_drawer ) ); //Why not? Of course works
    callback.push_back( [](){ /* draw code */ } ); //Ohhh, a lambda! Also works
    //Simulation/Drawing/Game loop
    while( true )
    {
        for( auto& callback : callback )
            the_function_which_really_draws( callback ); //Magic, isn't?
    }
}