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

调用多态Pokemon对象attacked函数遇编译错误:‘this’参数为const Pokemon

问题分析与解决方案

嘿,我来帮你拆解下这个编译错误的原因,其实问题出在你可能没注意到的lambda表达式细节上,还有一个明显的参数遗漏问题:

错误根源

  1. Lambda的const特性导致的问题
    你在QTimer::singleShot里用了[=]按值捕获变量,这会把sPokemon复制一份到lambda内部。默认情况下,lambda表达式的调用运算符operator()是const修饰的——这意味着lambda里的sPokemon副本是const Pokemon类型的。而你的attacked函数是非const成员函数,C++规定const对象不能调用非const成员函数,所以就出现了那个报错。

  2. attacked函数调用参数缺失
    你的Pokemon::attacked函数定义是void attacked(int value),明确需要传入一个int类型的伤害值,但你调用的时候写的是sPokemon.attacked(),完全没有传参数,这其实也是一个编译错误,只是编译器优先报了const相关的问题而已。

修复方案

针对这两个问题,我们可以这样修改:

方案一:按引用捕获变量(推荐)

直接用[&]按引用捕获,这样lambda内部操作的是原sPokemon对象,不会产生const副本,同时补上attacked需要的参数(比如用对方的攻击值作为参数):

void FightWidget::fight(Pokemon &mPokemon, Pokemon &sPokemon) {
    bool flag = false;
    // 注意:这里的while循环会无限创建定时器,实际运行会导致程序资源耗尽,必须补充终止逻辑
    while(flag == false) {
        QTimer::singleShot(200, this, [&]{ 
            // 传入攻击值,比如调用mPokemon的attack函数获取伤害
            sPokemon.attacked(mPokemon.attack()); 
            // 补充终止循环的逻辑,比如判断双方HP是否归零
            if (sPokemon.hp <= 0 || mPokemon.hp <= 0) {
                flag = true;
            }
        });
        // 注意:这里需要添加延迟或者事件循环处理,否则while会瞬间创建无数定时器
        // 比如可以用QEventLoop或者调整逻辑避免同步循环
    }
}

方案二:给lambda添加mutable关键字

如果你确实需要按值捕获,可以给lambda加上mutable关键字,这样lambda的operator()就会变成非const,内部的捕获变量也不再是const:

QTimer::singleShot(200, this, [=]() mutable { 
    sPokemon.attacked(mPokemon.attack()); 
});

额外提醒

你的fight函数里的while(flag == false)是同步循环,而QTimer::singleShot是异步执行的,这个循环会瞬间创建大量定时器,导致程序卡死。你需要调整逻辑,比如用事件循环或者在lambda内部判断终止条件,避免无限创建定时器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:52:56