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

C++存储于管理类中的类实例无法保留数据修改问题求助

问题原因

你遇到的_lastCheck无法更新的核心原因是遍历Action时发生了值拷贝,修改的是临时副本的属性,原实例完全没有被改动,分为两种场景:

  1. 最初使用vector<Action>存储的版本中,tick方法内的循环for(auto action : _actions)里的auto推导为Action类型,每次遍历都会把容器内的Action实例拷贝出一份临时变量,调用trigger修改的_lastCheck属于这个临时副本,循环结束后副本直接销毁,容器内的原实例属性没有任何变化。
  2. 即使你把addAction改成传引用或者改成指针存储,如果循环里还是对值类型做拷贝遍历,问题依然会存在。你修改为指针存储后依旧不生效,大概率是修改代码时有遗漏,或者用了旧的编译产物,只要代码修改完整,指针方案是可以正常运行的。

两种修复方案

方案1:不使用指针,仅修改遍历逻辑(更推荐,无需手动管理内存)

保持Action值存储的逻辑,只需把循环改为引用遍历,直接操作容器内的原实例即可:

class ActionManager {
public:
   // 传const引用优化,减少一次拷贝操作
   void addAction(const Action& action) {
       _actions.push_back(action);
   }
   
   void tick() {
       int now = millis();
       // 加&变成引用,直接操作容器内的原实例,不会产生拷贝
       for(auto& action : _actions) {
           if(action.trigger(now)) {
               action.fire();
           }
       }
   }
   
private:
  vector<Action> _actions;
};

方案2:指针存储方案(确认所有修改点完整即可生效)

你修改后的指针版本本身逻辑是成立的,只要确保_actions的类型是vector<Action*>、addAction接收指针参数、调用时传入实例地址三个点都修改正确,就可以正常更新_lastCheck的值:

class ActionManager {
public:
   void addAction(Action *action) {
       _actions.push_back(action);
   }
   
   void tick() {
       int now = millis();
       // 这里auto推导为Action*,拷贝的是指针本身,指向的还是原实例
       for(auto action : _actions) {
           if(action->trigger(now)) {
               action->fire();
           }
       }
   }
   
private:
  vector<Action *> _actions;
};

// 调用时传入地址
manager.addAction(&hiAction);
manager.addAction(&heyAction);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:24:02