如何将对象的成员函数指针传入函数?C3867错误咨询
解决C3867错误:成员函数指针的使用问题
错误原因分析
你遇到的Error C3867核心问题是非静态成员函数指针的语法规则和存储类型不匹配:
- 获取非静态成员函数的指针必须显式用
&类名::成员函数名的写法,不能直接写对象.成员函数 - 普通函数指针
void (*action)()无法存储成员函数指针——非静态成员函数隐含一个this指针参数,和普通函数的调用签名完全不兼容。
你的代码问题点
在main函数的这行代码里:
menu.addPar( {"Add note", note.addNote} );
note.addNote的写法不符合成员函数指针的获取语法par结构体中的action是普通函数指针,根本无法接收成员函数指针类型的值
解决方案(推荐:std::function + std::bind)
这种方式灵活性最高,支持绑定任意可调用对象(成员函数、普通函数、lambda等)。
- 修改
Menu.h的par结构体,引入std::function:
#include <functional> // 必须添加这个头文件到Menu.h开头 struct par { std::string name; std::function<void()> action; // 替换原有的普通函数指针 int order = 0; };
- 修改
main中的调用代码,用std::bind绑定对象和成员函数:
#include <functional> // main文件也需要包含这个头文件 int main() { Notebook note; Menu menu; // 绑定note对象的addNote成员函数,生成无参可调用对象 menu.addPar( {"Add note", std::bind(&Notebook::addNote, ¬e)} ); // 别忘了调用菜单入口:menu.callMenu("Notebook Menu"); }
替代方案:直接使用成员函数指针(局限性大)
如果不想用std::function,可以直接存储成员函数指针和对象指针,但这种方式只能适配Notebook类的成员函数:
- 修改
Menu.h的par结构体:
struct par { std::string name; void (Notebook::*action)(); // Notebook类的成员函数指针类型 Notebook* obj; // 对应的对象实例指针 int order = 0; };
- 修改
main的调用代码:
menu.addPar( {"Add note", &Notebook::addNote, ¬e} );
- 修改
Menu::callMenu中调用函数的逻辑:
// 替换原有的pars[menu].action(); (pars[menu].obj->*(pars[menu].action))();
额外提示
你的Menu::callMenu函数还有逻辑问题:
order变量未被正确赋值和使用,当前的if (i == pars[i].order)判断逻辑不符合预期- 必须在
main中调用menu.callMenu("你的菜单标题")才能启动菜单交互
内容的提问来源于stack exchange,提问作者user28112839
相关产品推荐
相关产品推荐

