如何向不带参数的函数(有参数)添加指针,并稍后使用自定义参数调用它们 C++

问题描述 投票:0回答:1

我会尽量保持简短。尽我所能。

我有一个法术类别,主要是持续时间、冷却时间、伤害、伤害类型等。 我有 SpellManager 类,它应该实例化法术,将它们提供给玩家或敌人,并跟踪实例化的每个(指针)法术。每个法术都有 3 个效果。就像火球术一样(随着时间的推移造成伤害,aoe,以及其他东西) - 具有不同参数的不同能力。

我有类似的东西

vector<function<void()>> _spell_effects;

在我的 Spell.h 中并有一个函数

void Spell::SetSpellEffects(vector<function<void()>> spell_effects) {
    _spell_effects = spell_effects;
}

在 Manager 实例化后将效果设置为法术实例,其工作方式如下

void SpellManager::CreateSpell(Character* spell_owner, ESpellID spell_id) {

    Spell* spell = Spell::CreateSpell(spell_id);
    string spell_name = GameplayStatics::GetEnumString(spell_id);
    map<string, Spell*> spell_instance;
    spell_instance[spell_name] = spell;

    if (dynamic_cast<PlayerCharacter*>(spell_owner) != nullptr) {
        _instanced_spells.push_back(spell_instance);
    }
    else {
        _instanced_enemy_spells.push_back(spell_instance);
    }

    GameplayStatics::AddSpellToCharacter(spell_owner, spell);
    
    AddSpellEffects(spell);
}

void SpellManager::AddSpellEffects(Spell* spell) {


    CharacterData data(ECharacterClass::BARBARIAN);
    PlayerCharacter* player = new PlayerCharacter(data.GetCharacterData(), data.GetPlayerAttributeData());

    CharacterData enemy_data(ECharacterClass::ENEMY);
    EnemyCharacter* enemy = new EnemyCharacter(enemy_data.GetCharacterData());
    enemy->name = "dzura";

    vector<Character*> enemies;
    enemies.push_back(enemy);

    vector<function<void()>> _effects;
    
    function<void()> Fireball_Default = [this, player, enemies]() {
        this->Fireball_Default(player, enemies);
    };
    _effects.push_back(Fireball_Default);

    function<void()> Fireball_Level2 = [this]() {
        this->Fireball_Level2();
    };
    _effects.push_back(Fireball_Level2);

    function<void()> Fireball_Level3 = [this]() {
        this->Fireball_Level3(5);
    };
    _effects.push_back(Fireball_Level3);

    spell->SetSpellEffects(_effects);

}

所以在主要方面我可以这样称呼它们

    CharacterData data(ECharacterClass::BARBARIAN);
    PlayerCharacter* player = new PlayerCharacter(data.GetCharacterData(), data.GetPlayerAttributeData());

    SpellManager spell_manager(player);

    spell_manager.CreateSpell(player, SPELL_FIREBALL);

    _enemies.push_back(enemy);

    player->GetActives()[0]->InvokeEffect(1);

拼写管理器然后跟踪指向 Spell 的指针并处理其他所有事情。 现在,使用 InvokeEffect(1),我可以调用咒语 1-3 的效果,但始终使用我在 lambda 中提供的相同参数来调用它们。我的问题是。有人可以重构代码,告诉我如何实例化 Spell,然后在 SpellManager 中向其添加 3 个 void 函数(这就是它们的定义位置),然后将该向量传递给 Spell 实例,并在用户输入时使用 InvokeEffect( 1-3) 但也有自定义参数?

我尝试了很多东西,我尝试了不同的数据结构,我尝试将法术效果直接添加到法术中,我要么无法让它工作,要么无法编译。此提供的代码仅适用于起始数据。 我应该以某种方式将这些传递到咒语的构造函数中吗?我该怎么做呢?我该如何称呼这些咒语? 我使用的一些数据结构


using Function = std::function<void(SpellManager&, vector<any>)>;

vector<map<string, vector<void(*)()>>> _effect_map;

这些都有效,我在其中跟踪

vector<map<string, Spell*>> _instanced_spells;

vector<map<string, Spell*>> _instanced_enemy_spells;

vector<pair<int, pair<string, Spell*>>> _active_spells;

我可以改变我的设计中的任何内容,我需要它才能工作。

c++ lambda void-pointers std-function
1个回答
0
投票

我使用 std::function 而不是 void 指针解决了这个问题,并在每个函数传递发起者、目标和指向 params 结构的指针(可以容纳所需的任意数量的参数)的地方进行了主要处理。现在,当它们都具有相同的签名时,就很容易解决了。

© www.soinside.com 2019 - 2024. All rights reserved.