[英]How do you delete both a pointer in a vector of pointers of Objects and the Object itself?
我正在嘗試編寫一個基於文本的冒險游戲構建器。 我有三個班級: Room
, Object
和我的main
班級。 在我的Room
類中,我有一個(專用) Objects
指針的vector<Object*> objectsInRoom
: vector<Object*> objectsInRoom
這樣可以跟蹤存儲在每個房間中的所有Objects
。 我在Room
類中有一個稱為objects()
的函數,當我在main
類中調用該vector時,該函數返回objectsInRooms
。
vector<Object*> Room::objects() { return objectsInRoom; }
在我的main
類中,在函數pickUpObject()
,我創建了一個稱為roomObject.
的Objects
指針向量roomObject.
我打電話objects()
在Room
階級和存儲Objects
中objectsInRoom
(這是只有在被訪問的Room
類)在roomObject
(這是在我的功能訪問main
)。 我還有一個稱為allObjects
的Objects
向量,用於存儲我要從房間拿起並隨身攜帶的所有物品。 它具有全球范圍。
我allObjects
,以便如果我在特定房間中拿到一個項目,則將該項目添加到allObjects
,刪除指向roomObjects
該元素的指針(以及指向Room
類中objectsInRooms
中該元素的指針),並且項目本身。
我的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;
}
}
}
我在StackOverflow上查找了各種帖子,以嘗試解決我的困境。 在main
,我創建了一個名為deleteVectorContent
的方法來嘗試刪除指針。
void deleteVectorContent(vector<Object*> objectVector, int start, int stop)
{
for (int k = start; k < stop; k++)
delete objectVector[k];
objectVector.clear();
}
我也嘗試過'roomObjects.remove()'從該房間中刪除項目本身。 但是,無論何時我編譯,我的編譯器也會拋出異常。 幫助將不勝感激。
PS此作業的鏈接在這里 。 如果您向下滾動到“編程分配的額外學分”,然后轉到第一個標記為“ 10分”的人,那就是我正在從事的工作。 非常感謝你的幫助!
Room::objects()
返回objectsInRoom
的副本 ,因此pickUpObject()
對返回的矢量進行的任何修改都不會應用回objectsInRoom
。 您需要使Room::objects()
返回對objectsInRoom
的引用 ,例如:
vector<Object*>& Room::objects()
{
return objectsInRoom;
}
void pickUpObject(vector<Object> &allObjects, Room* current)
{
vector<Object*> &roomObjects = current->objects();
...
}
否則,根本不提供直接訪問objectsInRoom
權限。 向Room
引入新方法以從其objectsInRoom
訪問/刪除給定的Object*
,例如:
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
接收的是實際Object
的副本 ,而不是Object*
指針。 當您制作*roomObjects[i]
的副本,然后在i
處erase()
Object*
erase()
Object*
而沒有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>
來保存所有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));
...
}
如果您絕對需要一個擁有Object*
指針的vector
,並且必須在銷毀該vector
之前對其進行清理,請考慮使用vector<unique_ptr<Object>>
,讓編譯器和STL為您處理艱巨的工作。 如果發現自己必須編寫諸如deleteVectorContent()
類的東西,請重新考慮您的設計。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.