在过去的几天里,我一直在编写一个系统,以便于编写基于文本的冒险(类似于Colossal Cave或Zork)。我一直遇到Item子系统的问题。
有关的三个课程是房间,门和项目。
当我从Room的项目向量中移除Item对象时,同一房间的Door向量中的最后一个Door对象已损坏。应该注意的是,所有Door和Item对象都是通过引用传递的,这允许人们编写自己的Door和Item子类,并且仍然将它们与系统一起使用。奇怪的是,门对象的唯一属性是“位置”属性,该属性告诉玩家门在房间的哪个位置。所有其他属性保持不变,这告诉我门对象的指针尚未移动,但它指向的数据已被更改。
这会导致玩家看到门描述的错误。为了测试,我没有给门特别说明,它们有太多,所以他们使用我的内部,罐头描述。
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]
玩家仍然可以从一个房间移动到另一个房间,因此门对象中的其余数据看似没问题。但是,存储“Location”属性的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链接。
答案 0 :(得分:3)
在您发布的代码中:
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
}
当您尝试删除它时,答案 1 :(得分:0)
Dewtell发现导致内存损坏的错误。但是,代码中的真正错误在于这一行:
int itemNum = ParentRoom->HasItem(Name);
应该是:
int itemNum = ParentRoom->HasItem(PickupName);
否则永远无法找到匹配。