C++中如何传递函数作为参数?二叉树调用成员函数报错求助
问题核心
你卡壳的地方是静态成员函数指针和普通/非成员函数指针的类型不兼容。Billete::mostrar作为静态函数,它的指针类型和非静态成员函数不一样(静态函数没有隐含的this参数),如果ArbolABB::InOrden的参数定义的是非静态成员函数指针,直接传&Billete::mostrar肯定会报错。
两种解决思路
思路1:把InOrden改成接受普通函数指针
因为静态成员函数本质和普通函数指针类型一致,直接调整InOrden的参数类型就能适配:
1. 修改arbolABB.h的InOrden声明
把原来的成员函数指针参数换成普通函数指针:
// 原来错误的声明可能是这样: // void InOrden(NodoABB* nodo, void (Billete::*func)(Billete*)); // 修改后: void InOrden(NodoABB* nodo, void (*func)(Billete*));
2. 调整arbolABB.cpp的InOrden实现
调用函数时直接传节点数据就行,不需要绑定对象:
void ArbolABB::InOrden(NodoABB* nodo, void (*func)(Billete*)) { if (nodo == nullptr) return; InOrden(nodo->izq, func); func(nodo->dato); // 直接调用静态函数 InOrden(nodo->der, func); }
3. 正常调用mostrar
现在在ArbolABB的mostrar函数里直接传&Billete::mostrar就没问题了:
void ArbolABB::mostrar() { InOrden(raiz, &Billete::mostrar); }
思路2:让InOrden兼容静态和非静态函数
如果以后需要支持非静态成员函数打印,把InOrden改成模板函数更灵活:
1. 重构arbolABB的InOrden为模板函数
// arbolABB.h 里声明模板函数 template <typename FuncType> void InOrden(NodoABB* nodo, FuncType func) { if (nodo == nullptr) return; InOrden(nodo->izq, func); func(nodo->dato); InOrden(nodo->der, func); }
2. 调用方式
静态函数直接传指针,非静态函数可以用lambda绑定对象:
void ArbolABB::mostrar() { // 静态函数直接传 InOrden(raiz, &Billete::mostrar); // 如果是Billete的非静态打印函数,比如print(): // Billete sampleObj; // InOrden(raiz, [&sampleObj](Billete* b){ sampleObj.print(b); }); }
关键知识点提醒
- 静态成员函数指针:类型是
返回值 (*)(参数列表),和普通函数指针完全兼容,调用时不需要对象。 - 非静态成员函数指针:类型是
返回值 (类名::*)(参数列表),必须绑定一个类对象才能调用(比如(obj.*func)(参数))。
内容的提问来源于stack exchange,提问作者Jaime
相关产品推荐
相关产品推荐

