我要实现一个约瑟夫环的功能,前端得到总数和出列编号,后端通过这个函数来走一遍约瑟夫环流程,这里用到了函数指针
template<class T>
void CircledLinkedList<T>::Josephus(int leaveIndex, void (*dowithLeave)(T data))
{
cirLinkedList pre = head, next = head->next;
int count = 1;
while (head->next != head) {
if(next == head) {
pre = pre->next;
next = next->next;
continue;
}
if(count == leaveIndex) {
count = 0;
}
count++;
if(count == leaveIndex) {
dowithLeave(pre->data);
pre->next = next->next;
free(next);
next = pre->next;
continue;
}
pre = pre->next;
next = next->next;
}
}
调用以上函数的函数如下,但是在调用的时候出现报错
void Widget::chooseKing()
{
monkeyqueue->Josephus(ui->leaveNum->value(), leaveQueue);//报错,错误信息如下
/*widget.cpp:72:50: error: reference to non-static member function must be called*/
}
void Widget::leaveQueue(monkeyLabel *leave)
{
ui->queueLeave->layout()->addWidget(leave);
QEventLoop eventloop;
QTimer::singleShot(1000, &eventloop, SLOT(quit()));
eventloop.exec();
}
错误的内容从我的理解角度是,leaveQueue函数不是static的,但是我看了很多示例,按理来说,用函数指针时,应该不会报这样的错。
如果我按报错的内容改,把leaveQueue定义成static的,那么leaveQueue函数内的ui这个变量就没法调用,静态函数里调用非静态变量,肯定不行。但是ui还不能再改成static了。
现在卡在这个地方了,进行不下去了,看了半天不知道为什么非得要静态变量。
成员函数leaveQueue第一个参数默认是this指针, 所以leaveQueue函数加上默认参数其实是2个参数。
所以你这里一种方法时把leaveQueue函数不放在类中,
另一种是leaveQueue加static修饰 ,静态函数就没有this指针,但你又调用了Widget成员函数。
这个是c++类设计时的规定,你只有改变你的实现方式了。
补充:
其实c++里面很少用原始的函数指针了,这样类型基本是在c中用的多
你可以了解下std::functional、function、bind,可调用对象的相关操作,是可以替代函数指针的,实现回调也很方便
个人愚见,函数指针必须得是全局的或者是静态的。可以维护一个widget的全局变量或者静态变量,在全局函数和静态函数里面使用,这样你就能使用ui了