我有一個向量 (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) {
cout << name << " cast (virtual)" << endl;
if (draw > 0 && capacity > 0) {
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) {
cout << name << " cast" << endl;
if (draw > 0 && capacity > 1) {
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)
Empty Slot cast (virtual)
Empty Slot cast (virtual)
Spark Bolt cast
Empty Slot cast (virtual)
if draw = 2 (所以整個向量都被投射)
uj5u.com熱心網友回復:
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;
}
您還需要在遞回之前檢查容量,以確保您不會取消參考過去的結束迭代器:
if (capacity > 1) {
(*me)->cast(me, pos, 0.0f, capacity - 1, draw);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/532082.html
標籤:C 目的向量
上一篇:從類用戶輸入創建串列
