2013-05-30 66 views
0

为了避免代码重复,我打算将指针指向函数作为静态方法的参数。作为参数的方法指针

我有一个只有静态方法的类(地理)。其中一种方法(+++ Geo :: traceRay(+++))应该只显示(Geo :: display(+++))几件事情,然后返回一个int。另一个类(拉斯维加斯)需要使用Geo :: traceRay(+++)方法,但是应该显示其他的(Las :: display(+++))。 所以我尝试将函数参数的指针传递给Geo :: traceRay(+++,指向函数的指针)方法。指向的函数将会右键“显示()”方法。

到目前为止,将第一个指针传递给display()不是问题,但我找不到第二个指针。

class Geo 
{ 
public: 
    static bool display(int pix); 
    static int traceRay(int start, int end, bool (*func)(int) = &Geo::display); // no issue with this default parameter 
}; 


class Las 
{ 
public: 
    bool display(int pix); 
    void run(); 
}; 


int Geo::traceRay(int start, int end, bool (*func)(int)) 
{ 
    for (int i = start; i < end ; ++i) 
    { 
     if((*func)(i)) return i; 
    } 
    return end; 
} 

bool Geo::display(int pix) 
{ 
    cout << pix*100 << endl; 
    return false; 
} 


bool Las::display(int pix) 
{ 
    cout << pix << endl; 
    if (pix == 6) return true; 
    return false; 
} 

void Las::run() 
{ 
    bool (Las::*myPointerToFunc)(int) = &display;  // I can just use display as a non member class, but it should stay a member 
    Geo::traceRay(0,10, myPointerToFunc);    // issue here! 
} 


int main() 
{ 
    Geo::traceRay(0,10); // use the "normal display" = the default one// OK 

    Las myLas; 
    myLas.run(); 

    return 0; 
} 

回答

0

您不能将成员函数指针作为函数指针传递。我认为制作Las::display静态不是一个选项。在这种情况下,我建议采取std::function并使用std::bind当前实例绑定:

static int traceRay(int start, int end, std::function<bool(int)> func = &Geo::display); 
... 
Geo::traceRay(0,10, std::bind(&Las::display, this, std::placeholders::_1)); 

此外,在这两种情况下,你可以调用func

func(i); 

无需取消对它的引用第一。

+0

非常感谢这个答案。我不知道'std :: function'和'std :: bind'。我需要[链接](http://latedev.wordpress.com/2012/08/06/using-stdbind-for-fun-and-profit/)了解它是如何工作的,但现在我已经完全符合我的要求。另外,要从Las类调用Geo :: traceRay,必须使用Geo :: traceRay(0,10,std :: bind(&Las :: display,this,std :: placeholders :: _ 1));' – n3squik

+0

@ n3squik,哦,对不起。那么我会更新我的答案。 – chris

0

克里斯建议如果这样的话,那就太好了。

对此的另一种方法是,如果您有几个共享函数,这将是有益的,将使用两个实现的接口(使用虚拟方法Display(+++)),将实现的实例在Geo和Las的每一个中都有问题(或Las可以直接实现这个接口)。然后traceRay引用接口基类并调用其上的显示方法。