You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将对象的成员函数指针传入函数?C3867错误咨询

解决C3867错误:成员函数指针的使用问题

错误原因分析

你遇到的Error C3867核心问题是非静态成员函数指针的语法规则和存储类型不匹配:

  1. 获取非静态成员函数的指针必须显式用&类名::成员函数名的写法,不能直接写对象.成员函数
  2. 普通函数指针void (*action)()无法存储成员函数指针——非静态成员函数隐含一个this指针参数,和普通函数的调用签名完全不兼容。

你的代码问题点

在main函数的这行代码里:

menu.addPar( {"Add note", note.addNote} );
  • note.addNote的写法不符合成员函数指针的获取语法
  • par结构体中的action是普通函数指针,根本无法接收成员函数指针类型的值

解决方案(推荐:std::function + std::bind)

这种方式灵活性最高,支持绑定任意可调用对象(成员函数、普通函数、lambda等)。

  1. 修改Menu.h的par结构体,引入std::function:
#include <functional> // 必须添加这个头文件到Menu.h开头

struct par
{
    std::string name;
    std::function<void()> action; // 替换原有的普通函数指针
    int order = 0;
};
  1. 修改main中的调用代码,用std::bind绑定对象和成员函数:
#include <functional> // main文件也需要包含这个头文件

int main()
{
    Notebook note;
    Menu menu;
    // 绑定note对象的addNote成员函数,生成无参可调用对象
    menu.addPar( {"Add note", std::bind(&Notebook::addNote, &note)} );
    // 别忘了调用菜单入口:menu.callMenu("Notebook Menu");
}

替代方案:直接使用成员函数指针(局限性大)

如果不想用std::function,可以直接存储成员函数指针和对象指针,但这种方式只能适配Notebook类的成员函数:

  1. 修改Menu.h的par结构体:
struct par
{
    std::string name;
    void (Notebook::*action)(); // Notebook类的成员函数指针类型
    Notebook* obj; // 对应的对象实例指针
    int order = 0;
};
  1. 修改main的调用代码:
menu.addPar( {"Add note", &Notebook::addNote, &note} );
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:52:33