如何删除对象指针向量和对象本身中的指针?

时间:2018-01-25 00:05:26

标签: c++ pointers vector

我正在尝试编写基于文本的冒险游戏构建器。我有三个课程:RoomObject和我的main课程。在我的Room课程中,我有一个(私人)指针向量Objectsvector<Object*> objectsInRoom

这会跟踪每个房间中存储的所有Objects。我在objects()类中有一个名为Room的函数,当我在objectsInRooms类中调用该向量时,它返回main

vector<Object*> Room::objects() {   return objectsInRoom;  }

在我的main课程中,在我的函数pickUpObject()中,我创建了一个名为Objects roomObject.的指针向量,我在objects()中调用Room Objects类将objectsInRoom存储在RoomroomObject(仅在main类中访问)Objects(我的函数allObjects中可以访问allObjects 1}})。我还有一个名为roomObjects的{​​{1}}向量,它存储了我想要从房间里拿起的所有物品并随身携带。它具有全球范围。

我想这样做,如果我在特定房间拿起一个项目,我将项目添加到objectsInRooms,删除Room中指向该元素的指针(从而指向pickUpObjectRoom* current中该元素的指针,以及项目本身。

我的Objects功能是:(void pickUpObject(vector<Object>&allObjects, Room* current) { vector<Object*>roomObjects; int length; string name; char flag; roomObjects = current->objects(); length = roomObjects.size(); bool repeat = true; while (repeat) { if (length == 0) { cout << "There are no objects to pick up in " << current->name() << endl; repeat = false; } else { cout << "There is a "; for (int k = 0; k < roomObjects.size() - 1; k++) { cout << roomObjects[k]->getName(); if (length > 2) cout << ", "; } if (length > 1) cout << " and " << roomObjects[length - 1]->getName() << " here." << endl; else cout << roomObjects[length-1]->getName() << "." << endl; cout << "What object do you want to pick up?" << endl; cin >> name; //this is where the deletion happens for (int i = 0; i < length; i++) if (name.compare(roomObjects[i]->getName()) == 0) { allObjects.push_back(*roomObjects[i]); roomObjects.erase(roomObjects.begin() + i); deleteVectorContent(roomObjects, i, i + 1); } cout << "roomObject size = " << roomObjects.size() << endl; cout << "--------------------" << endl; cout << "allObject size = " << allObjects.size() << endl; for (int i = 0; i < allObjects.size(); i++) cout << allObjects[i].getName() << endl; for (int i = 0; i < roomObjects.size(); i++) { cout << roomObjects[i]->getName() << endl; } cout << "Do you want to pick up another object? (Y/N): "; cin >> flag; if (flag == 'N') repeat = false; } } } 只是告诉我我在哪个房间,因此main我有什么样的身材

deleteVectorContent

我查阅了StackOverflow上的各种帖子,试图解决我的困境。在void deleteVectorContent(vector<Object*> objectVector, int start, int stop) { for (int k = start; k < stop; k++) delete objectVector[k]; objectVector.clear(); } 中,我创建了一个名为Select * from DeviceLog where EnergyConsumed <= 10000 and LogDateTime between '2018-01-15' and '2018-01-18' 的方法来尝试删除指针。

@beforeClass

我还试过'roomObjects.remove()'从该房间中删除项目本身。然而,每当我编译时,我的编译器也会抛出异常。非常感谢帮助。

P.S。此作业的链接是here。如果向下滚动到“编程分配的额外信用”并转到标记为“10分”的第一个,这就是我正在进行的工作。非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

Room::objects()正在返回objectsInRoom副本,因此pickUpObject()对该返回的向量所做的任何修改都不会应用回{{1} }。您需要objectsInRoom引用返回Room::objects(),例如:

objectsInRoom

否则,请勿提供对vector<Object*>& Room::objects() { return objectsInRoom; } void pickUpObject(vector<Object> &allObjects, Room* current) { vector<Object*> &roomObjects = current->objects(); ... } 直接访问权限。向objectsInRoom引入新方法,以便从Room访问/删除给定Object*,例如:

objectsInRoom

请注意int Room::numObjects() { return objectsInRoom.size(); } Object* Room::getObject(int index) { return objectsInRoom[index]; } Object* Room::takeObject(int index) { Object *obj = objectsInRoom[index]; objectsInRoom.erase(objectsInRoom.begin()+index); return obj; } void pickUpObject(vector<Object> &allObjects, Room* current) { int length = current->numObjects(); ... for (int i = 0; i < length; ++i) { if (name == current->getObject(i)->getName()) { Object *obj = current->takeObject(i); allObjects.push_back(*obj); delete obj; break; } } ... } 正在接收实际allObjects s的副本,而不是Object指针。您展示的代码是在Object*复制*roomObjects[i]然后erase() Object* idelete没有Object Object时泄露内存它正指向。如果Object*非常易于复制,那么只需删除所有Object指针并在任何地方使用class Room { vector<Object> objectsInRoom; ... }; int Room::numObjects() { return objectsInRoom.size(); } Object& Room::getObject(int index) { return objectsInRoom[index]; } Object Room::takeObject(int index) { Object obj = objectsInRoom[index]; objectsInRoom.erase(objectsInRoom.begin()+index); return obj; } void pickUpObject(vector<Object> &allObjects, Room* current) { int length = current->numObjects(); ... for (int i = 0; i < length; ++i) { if (name == current->getObject(i)->getName()) { allObjects.push_back(current->takeObject(i)); break; } } .... } ,就可以省去很多麻烦:

Object

否则,请不要像以前那样将Object*Object*混合,在任何地方都使用Object

如果你有一套固定的游戏vector<Object>,我会创建一个全局Object*来保存它们,然后根据需要随处传递vector<Object> allGameObjects; // fill as needed... void Room::addObject(Object *obj) { objectsInRoom.push_back(obj); } Object* Room::takeObject(int index) { Object *obj = objectsInRoom[index]; objectsInRoom.erase(objectsInRoom.begin()+index); return obj; } void pickUpObject(vector<Object*> &allObjects, Room* current) { ... allObjects.push_back(current->takeObject(i)); ... } 个指针。然后您根本不必担心手动清理内存:

vector

如果您绝对需要拥有Object*指针的vector必须在vector<unique_ptr<Object>>被销毁之前进行清理,请考虑使用deleteVectorContent(),让编译器和STL为您处理艰苦的工作。如果您发现自己必须写{{1}}之类的内容,请重新考虑您的设计。