如何在函数指向类函数但在该类之外时正确调用该函数

时间:2014-01-26 15:15:40

标签: c++ class pointers struct function-pointers

很抱歉,如果这个标题措辞不当......但这就是我要做的......

我有一个结构“屏幕”,它有一个指向这些函数的指针,这些函数是“Test”类的成员......

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

     ...

}

我在创建我的Test实例“test”时指定了drawfunc指针......这对我来说很奇怪,我不完全理解它,但是它编译了......

Test::Test()
{

     ...

     tscreen->drawfunc=&Test::draw;

     ...

}

但是我无法弄清楚如何在我的main中调用drawfunc函数...我正在尝试这样并且它给出错误“错误C2064:术语不评估为采用4个参数的函数”< / p>

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的类“Test”的哪个实例可以工作...即使所有变量和指向函数本身的指针都来自实例“test”。 ..

......并且对于不可避免的“你为什么还要尝试这样做?”回复...或者如果没有办法调用该函数或其他东西......我真的只是希望能够为“drawfunc”分配不同的函数,我希望这些函数能够使用所有的变量在实例“test”中,我可以得到它所以drawfunc指向任何旧函数(bool( drawfunc)(b2World ,objectdata *,actorlist *,camera *);),但它需要是能够访问Test实例“test”中的其他变量。所以...真的,不管你做了什么,那也很棒。感谢。

2 个答案:

答案 0 :(得分:2)

你这样做:

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

通常,间接指向成员的指针涉及使用->*.*运算符。如果您有指向对象a和指向成员b的指针,那么您会说a ->* b。在您的情况下,指向对象的指针为test,指向成员的指针为test->tscreen->drawfunc。额外的括号是必要的,因为->*是一个二元运算符,它的优先级低于后缀函数调用运算符(),但是你想在调用它之前间接指向成员的指针。

答案 1 :(得分:1)

最简单的方法是不直接使用函数指针并用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?
    }
}