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

在Visual Studio 2017中如何将类方法作为参数结合Lambda使用?

没问题,我来一步步帮你实现这个需求,用类成员函数指针结合Lambda让代码更灵活,下面是具体的步骤和完整示例:

实现类方法指针的传递与Lambda调用

1. 先定义类成员函数指针的类型

类的非静态成员函数指针必须带上类的作用域,为了避免重复写冗长的类型,我们可以用using给它起个别名:

// 在CMFCApplicationDlg类内部定义
using MethodPtr = void (CMFCApplicationDlg::*)();

这个别名代表CMFCApplicationDlg类中无参数、无返回值的成员函数指针,刚好匹配你的Add_text方法类型。

2. 修改Start_adding方法,接收成员函数指针参数

把Start_adding改成接受一个MethodPtr类型的参数,这样就能灵活传入不同的类方法:

void CMFCApplicationDlg::Start_adding(MethodPtr method_ptr);

3. 在Lambda中调用成员函数指针

因为Lambda捕获了当前对象的this指针,所以需要用(this->*method_ptr)()的语法来调用成员函数指针——这里的->*是专门用于成员指针的调用运算符,括号不能少(否则会因运算符优先级出错)。

完整示例代码

头文件(CMFCApplicationDlg.h)

#pragma once
#include <afxwin.h>
#include <fstream>

// 模拟调度器类(如果你的sched是现成库的对象,直接用就行)
class Scheduler {
public:
    template<typename Func>
    void cron(const char* expr, Func func) {
        // 这里只是模拟定时逻辑,实际会按 cron 表达式执行func
        func(); // 临时调用一次用于测试
    }
};

class CMFCApplicationDlg : public CDialogEx {
public:
    CMFCApplicationDlg(CWnd* pParent = nullptr);
    enum { IDD = IDD_MFCAPPLICATION_DIALOG };

protected:
    virtual void DoDataExchange(CDataExchange* pDX);

private:
    Scheduler sched;
    // 定义成员函数指针的别名
    using MethodPtr = void (CMFCApplicationDlg::*)();

    void Add_text();
    void Another_text(); // 额外加一个测试方法
    void Start_adding(MethodPtr method_ptr);

    // 按钮点击事件示例(需要在资源里绑定)
    afx_msg void OnBnClickedButtonStart();
    DECLARE_MESSAGE_MAP()
};

实现文件(CMFCApplicationDlg.cpp)

#include "pch.h"
#include "CMFCApplicationDlg.h"

CMFCApplicationDlg::CMFCApplicationDlg(CWnd* pParent)
    : CDialogEx(IDD_MFCAPPLICATION_DIALOG, pParent) {}

void CMFCApplicationDlg::DoDataExchange(CDataExchange* pDX) {
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMFCApplicationDlg, CDialogEx)
    ON_BN_CLICKED(IDC_BUTTON_START, &CMFCApplicationDlg::OnBnClickedButtonStart)
END_MESSAGE_MAP()

void CMFCApplicationDlg::Add_text() {
    std::ofstream outfile;
    outfile.open("test.txt", std::ios_base::app);
    outfile << "text added" << std::endl;
}

void CMFCApplicationDlg::Another_text() {
    std::ofstream outfile;
    outfile.open("test.txt", std::ios_base::app);
    outfile << "another text added" << std::endl;
}

void CMFCApplicationDlg::Start_adding(MethodPtr method_ptr) {
    sched.cron("0 12 * * *", [this, method_ptr]() {
        // 调用传入的成员函数指针
        (this->*method_ptr)();
    });
}

void CMFCApplicationDlg::OnBnClickedButtonStart() {
    // 传入Add_text的成员函数指针
    Start_adding(&CMFCApplicationDlg::Add_text);
    
    // 也可以轻松切换成另一个方法
    // Start_adding(&CMFCApplicationDlg::Another_text);
}

关键注意点

  • 获取成员函数指针时,必须写&CMFCApplicationDlg::Add_text,不能省略&和类作用域;
  • Lambda中调用成员指针的语法(this->*method_ptr)()必须带括号,否则会因运算符优先级问题编译失败;
  • 如果你需要支持带参数的成员函数,可以修改MethodPtr的类型,比如using MethodPtrWithParam = void (CMFCApplicationDlg::*)(int);,调用时传入对应参数即可。

内容的提问来源于stack exchange,提问作者maynull

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:10:51