gpt4 book ai didi

c++ - 从 vector 中删除对象会破坏 C++ 中另一个对象中的对象

转载 作者:太空狗 更新时间:2023-10-29 21:28:27 25 4
gpt4 key购买 nike

在过去的几天里,我一直在编写一个系统来简化基于文本的冒险的编写(类似于 Colossal Cave 或 Zork)。我一直遇到 Item 子系统的问题。

相关的三个类是 Room、Door 和 Item。

当我从 Room 的项目 vector 中删除 Item 对象时,同一房间的 Door vector 中的最后一个 Door 对象已损坏。应该注意的是,所有的门和项目对象都是通过引用传递的,这允许人们编写自己的门和项目子类并仍然在系统中使用它们。奇怪的是,要损坏的门对象的唯一属性是“位置”属性,它告诉玩家门在房间中的位置。所有其他属性都保持不变,这告诉我指向门对象的指针没有移动,但它指向的数据已被更改。

这会导致玩家看到门描述的方式出现错误。为了测试,我没有对门进行特殊描述,它们太多了,所以它们使用我内部的固定描述。

You are in a large parlour room.  It is obviously that of a very wealthy man.
Adorning the walls are many dusty heads of big game.
There is a door in the direction of West.
There is a door in the direction of East.
There is a door in the direction of North.
Hanging on the wall, you see a really bad ass looking sword.
Parlour] pickup sword
Picked up the Sword of the Gods
You pick up the sword.
In doing so, you feel very powerful.
There is a door in the direction of West.
There is a door in the direction of East.
There is a door in the direction of ?.
Parlour]

玩家仍然可以从一个房间移动到另一个房间,所以门对象中的其余数据似乎没问题。但是,存储“位置”属性的 std::string 已更改。我没有在代码的任何地方更改该属性。

谁能看出为什么会这样?我的代码或对象处理中是否存在明显的错误?因为我无法确定这是在哪个文件中发生的,所以有很多代码要发布。

您可以在此处下载我所有代码的 zip 文件:http://www.filedropper.com/advsys

这是我的代码,这当然不是全部,因为我在 9 个文件中有 467 行
当您试图拿起剑时调用此方法。

void OnPickup() {
std::cout << "You pick up the sword." << std::endl;
std::cout << "In doing so, you feel very powerful." << std::endl;

int itemNum = ParentRoom->HasItem(Name);
if (itemNum != -1) {
// Wait, the item ISN'T in the room? Then how the hell did we get HERE?
// Whatever, error out.
std::cout << "For some strange reason, you were hallucinating about the " + Name + "." << std::endl;
} else {
PlayerRef->Inventory.push_back(new GodSword(ParentRoom, PlayerRef));
ParentRoom->RemoveItem(itemNum); // Corrupts a door
//delete ParentRoom->Items[itemNum]; // SEGFAULT
}
}

门和元素是这样分配的。向新的 Door 实例传递文本位置、它在房间内的位置以及指向目的地的指针。元素被传递到它们所在房间的引用,以及对玩家的引用。

house["parlour"].Doors.push_back(new Door("North", 'N', &house["bedroom"]));
house["parlour"].Items.push_back(new GodSword(&house["parlour"], &player));

像这样从房间中删除项目。打印门列表以进行调试。

void Room::RemoveItem(int item) {
Items.erase(Items.begin() + item);

for (int i = 0; i < Doors.size(); i++) {
std::cout << Doors[i]->GetDescription() << std::endl;
}
}

房间声明如下。

class Room {
public:
std::vector<Door *> Doors;
std::vector<Item *> Items;

std::string LongDescription;
std::string ShortDescription;
std::string Name;

bool DescribeDoors;
bool DescribeItems;
bool BeenHere;

Room();
~Room();

int HasDoor(char dir);
int HasItem(std::string name);
void OutputDescription(bool forceLong=false);
void RemoveItem(int item);
};

我想不出还有什么需要补充的。如果您需要查看另一个文件,或者不同类的声明方式等...上面有一个 zip 链接。

最佳答案

在您发布的这段代码中:

   int itemNum = ParentRoom->HasItem(Name);
if (itemNum != -1) {
// Wait, the item ISN'T in the room? Then how the hell did we get HERE?
// Whatever, error out.
std::cout << "For some strange reason, you were hallucinating about the " + Name + "." << std::endl;
} else {
PlayerRef->Inventory.push_back(new GodSword(ParentRoom, PlayerRef));
ParentRoom->RemoveItem(itemNum); // Corrupts a door
//delete ParentRoom->Items[itemNum]; // SEGFAULT
}

当您尝试删除它时,itemNum 将为 -1,这可能会导致您注意到的段错误/内存损坏。测试的意义是否与应有的意义相反?

关于c++ - 从 vector 中删除对象会破坏 C++ 中另一个对象中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6947390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com