我正在尝试编写基于文本的冒险游戏构建器。我有三个课程:Room
,Object
和我的main
课程。在我的Room
课程中,我有一个(私人)指针向量Objects
:vector<Object*> objectsInRoom
这会跟踪每个房间中存储的所有Objects
。我在objects()
类中有一个名为Room
的函数,当我在objectsInRooms
类中调用该向量时,它返回main
。
vector<Object*> Room::objects() { return objectsInRoom; }
在我的main
课程中,在我的函数pickUpObject()
中,我创建了一个名为Objects
roomObject.
的指针向量,我在objects()
中调用Room
Objects
类将objectsInRoom
存储在Room
中roomObject
(仅在main
类中访问)Objects
(我的函数allObjects
中可以访问allObjects
1}})。我还有一个名为roomObjects
的{{1}}向量,它存储了我想要从房间里拿起的所有物品并随身携带。它具有全球范围。
我想这样做,如果我在特定房间拿起一个项目,我将项目添加到objectsInRooms
,删除Room
中指向该元素的指针(从而指向pickUpObject
类Room* 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分”的第一个,这就是我正在进行的工作。非常感谢你的帮助!
答案 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*
i
而delete
没有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}}之类的内容,请重新考虑您的设计。