簡體   English   中英

如何刪除對象指針向量中的指針和對象本身?

[英]How do you delete both a pointer in a vector of pointers of Objects and the Object itself?

我正在嘗試編寫一個基於文本的冒險游戲構建器。 我有三個班級: RoomObject和我的main班級。 在我的Room類中,我有一個(專用) Objects指針的vector<Object*> objectsInRoomvector<Object*> objectsInRoom

這樣可以跟蹤存儲在每個房間中的所有Objects 我在Room類中有一個稱為objects()的函數,當我在main類中調用該vector時,該函數返回objectsInRooms

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

在我的main類中,在函數pickUpObject() ,我創建了一個稱為roomObject.Objects指針向量roomObject. 我打電話objects()Room階級和存儲ObjectsobjectsInRoom (這是只有在被訪問的Room類)在roomObject (這是在我的功能訪問main )。 我還有一個稱為allObjectsObjects向量,用於存儲我要從房間拿起並隨身攜帶的所有物品。 它具有全球范圍。

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]的副本,然后在ierase() 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;
        }
    }
    ....
}

否則,不要像您一樣將ObjectObject*混合使用,請在各處使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM