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

如何将类成员函数作为函数指针传入StateMachine的addState方法

问题描述

想在自定义的MyStateMachine类中使用StateMachine类,但不想继承它,仅通过调用其函数封装逻辑。

现有代码

MyStateMachine.h

#include <StateMachine.h>

class MyStateMachine {
 public:
    void Initialisation();

 private:
    StateMachine machine = StateMachine();
    State* m0Initialisation = machine.addState(&Initialisation); // 此处报错
};

MyStateMachine.cpp

#include "MyStateMachine.h"

void MyStateMachine::Initialisation() {
   // 初始化操作逻辑
}

函数声明与编译错误

StateMachine::addState的声明为:

State* addState(void (*functionPointer)());

编译时触发错误:

error: no matching function for call to 'StateMachine::addState(void (MyStateMachine::*)())
note: State* StateMachine::addState(void (*)())
     State* addState(void (*functionPointer)());
note:   no known conversion for argument 1 from 'void (MyStateMachine::*)()' to 'void (*)()'
Compilation error: no matching function for call to 'StateMachine::addState(void (MyStateMachine::*)())'

已知类成员函数依赖对象实例,无法直接转换成普通函数指针;若将Initialisation定义在类外则可正常传入指针。现需解决:不借助外部库(如std::bind)的情况下,如何将类成员函数传入addState?


解决方案

核心逻辑是用静态成员函数做中转,结合类实例指针完成成员函数的间接调用,绕过普通函数指针与成员函数指针的类型不兼容问题。

实现步骤

  1. 添加静态成员变量保存MyStateMachine的实例指针
  2. 编写静态中转函数,通过实例指针调用目标成员函数
  3. 将静态中转函数传入addState,同时调整成员初始化顺序避免未定义行为

修改后的代码

MyStateMachine.h

#include <StateMachine.h>

class MyStateMachine {
 public:
    MyStateMachine() {
        // 构造函数中保存当前实例指针
        s_instance = this;
        // 移至构造函数初始化状态,避免成员初始化顺序问题
        m0Initialisation = machine.addState(&StaticInitialisation);
    }
    void Initialisation();

 private:
    static MyStateMachine* s_instance; // 静态指针存储实例
    static void StaticInitialisation(); // 静态中转函数
    StateMachine machine;
    State* m0Initialisation;
};

MyStateMachine.cpp

#include "MyStateMachine.h"

// 初始化静态成员变量
MyStateMachine* MyStateMachine::s_instance = nullptr;

void MyStateMachine::Initialisation() {
   // 初始化操作逻辑
}

void MyStateMachine::StaticInitialisation() {
    // 通过静态指针调用目标成员函数
    if (s_instance != nullptr) {
        s_instance->Initialisation();
    }
}

多实例场景优化(可选)

如果MyStateMachine需要支持多实例,静态指针会导致冲突。若能修改StateMachine源码,可扩展addState支持上下文参数:

// 修改StateMachine的addState声明
State* addState(void (*functionPointer)(void*), void* context);

对应调整中转函数与调用逻辑:

// 静态中转函数改为带上下文参数
static void StaticInitialisation(void* context) {
    MyStateMachine* instance = static_cast<MyStateMachine*>(context);
    instance->Initialisation();
}

// 构造函数中传入当前实例作为上下文
m0Initialisation = machine.addState(&StaticInitialisation, this);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:25:19