【问题标题】:Vector of object pointers recursive function using next object pointer in vector使用向量中的下一个对象指针的对象指针向量递归函数
【发布时间】:2022-11-13 20:31:43
【问题描述】:

我有一个向量 (vector<Spell *> spells;) 并且我希望能够在向量的第一个元素上调用 cast() 函数并让咒语在向量中施放 Spell* 但程序会到达

me->cast(me, pos, 0.0f, capacity-1, draw);

并在该行上启动一个无限循环,最终使程序崩溃。

我的代码:

#include <iostream>
#include <vector>

using namespace std;

typedef struct Vector2 {
    float x;
    float y;
} Vector2;

class Spell {
protected:
    Vector2 pos;
    string name;
public:
    Spell() {
        pos = {1, 2};
        name = "Empty Slot";
    }
    virtual void cast(Spell *me, Vector2 from, float angle, int capacity, int draw) {
        if (draw > 0 && capacity > 0) {
            cout << name << " cast (virtual)" << endl;
            me++;
            me->cast(me, pos, 0.0f, capacity-1, draw);
        }
    }
};

class SparkBolt : public Spell {
public:
    SparkBolt () {
        pos = {0, 0};
        name = "Spark Bolt";
    }
    void cast(Spell *me, Vector2 from, float angle, int capacity, int draw) {
        if (draw > 0 && capacity > 1) {
            cout << name << " cast" << endl;
            me++;
            me->cast(me, pos, 0.0f, capacity-1, draw-1);
        }
    }
};

class SpellStorage {
private:
    int capacity;
    vector<Spell *> spells;
public:
    explicit SpellStorage(int capacity) {
        SpellStorage::capacity = capacity;
        for (int i = 0; i < capacity; i++) {
            spells.emplace_back(new Spell());
        }
    }
    void insertSpell(Spell *spell, int slot) {
        spells.at(slot-1) = spell;
    }
    void cast() {
        spells.at(0)->cast(spells.at(0), {3.0f, 4.0f}, 0.0f, capacity, 1);
    }
};

//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main() {
    SpellStorage test = SpellStorage(5);

    test.insertSpell(new SparkBolt(), 4);
    test.cast();
    return 0;
}

在我意识到向量必须是一个 Spell 指针向量才能使 Cast() 多态性工作之前,代码运行良好,但在将最后一个 Spell 投射到向量中后会返回一个 sigsev 错误。

我期待程序打印:

Empty Slot cast (virtual)
Empty Slot cast (virtual)
Empty Slot cast (virtual)
Spark Bolt cast
Empty Slot cast (virtual)

【问题讨论】:

  • 您是否尝试过使用调试器单步执行代码以查看卡住的原因?为什么还要为此使用递归?你认为me++ 做了什么?因为它肯定不会遍历任何向量。
  • me 作为参数不是必需的,它被称为this(尽管类型是最后代的)。

标签: c++ object vector


【解决方案1】:

me++ 增加指针,但 me 不是指向数组的指针,因此您的代码具有未定义的行为。向量中的每个指针都与其余指针无关,您不能使用指针算术在它们之间遍历。您最好使用迭代器:

#include <iostream>
#include <vector>

using namespace std;

typedef struct Vector2 {
  float x;
  float y;
} Vector2;

class Spell {
protected:
  Vector2 pos;
  string name;
public:
  Spell() {
    pos = { 1, 2 };
    name = "Empty Slot";
  }
  virtual void cast(std::vector<Spell*>::iterator me, Vector2 from, float angle, int capacity, int draw) {
    if (draw > 0 && capacity > 0) {
      cout << name << " cast (virtual)" << endl;
      me++;
      (*me)->cast(me, pos, 0.0f, capacity - 1, draw);
    }
  }
};

class SparkBolt : public Spell {
public:
  SparkBolt() {
    pos = { 0, 0 };
    name = "Spark Bolt";
  }
  void cast(std::vector<Spell*>::iterator me, Vector2 from, float angle, int capacity, int draw) {
    if (draw > 0 && capacity > 1) {
      cout << name << " cast" << endl;
      me++;
      (*me)->cast(me, pos, 0.0f, capacity - 1, draw - 1);
    }
  }
};

class SpellStorage {
private:
  int capacity;
  vector<Spell*> spells;
public:
  explicit SpellStorage(int capacity) {
    SpellStorage::capacity = capacity;
    for (int i = 0; i < capacity; i++) {
      spells.emplace_back(new Spell());
    }
  }
  void insertSpell(Spell* spell, int slot) {
    spells.at(slot - 1) = spell;
  }
  void cast() {
    spells.at(0)->cast(spells.begin(), { 3.0f, 4.0f }, 0.0f, capacity, 1);
  }
};

//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main() {
  SpellStorage test = SpellStorage(5);

  test.insertSpell(new SparkBolt(), 4);
  test.cast();
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 2011-02-11
    • 2018-09-17
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多