【问题标题】:C++ STL vector.erase() always deletes last elementC++ STL vector.erase() 总是删除最后一个元素
【发布时间】:2013-05-22 03:09:56
【问题描述】:

使用:Eclipse 3.8.1、C/C++ Remote Debug Launcher 6.0.0、GCC 1.1.0 和 GDB 7.0.0 验证于:Visual Studio 2010

我正在把头发拉出来。使用以下代码时,房间对象 rooms 的向量的最后一个元素总是被删除。除了最后一个使用此代码擦除之外,我无法获得任何元素。我只是想删除一个元素(位置由用户确定)。

我知道你们中的许多人可能会问我为什么不使用列表,但随机数据访问比使用此集合轻松添加/删除元素更重要。你有什么想法吗?

void House::removeRoom(unsigned int roomToRemove){
    try{
        if(roomDoesNotExist(roomToRemove)) throw houseException("Room requested to     remove does not exist", roomToRemove, __FILE__, __LINE__);

        vector<Room>::iterator roomIterator = rooms.begin() + roomToRemove;
        rooms.erase(roomIterator);

        removeAllLinksToRoom(roomToRemove);
        renumberLinkedRoomsAfterErase(roomToRemove);
    }
    catch(houseException& hException){
        hException.display(cerr);
    }
}

这是 House 类的 sn-p:

#include "Room.h"

using namespace std;

class House {
public:
    vector<Room> rooms;

    //member functions
    void removeRoom(unsigned int roomToRemove);


    //constuctors / destructors
    House();
    virtual ~House();

    //STL linked list overload operators =, ==, and <
    House &operator=(const House &rhs);
    int operator==(const House &rhs) const;
    int operator<(const House &rhs) const;

private:
    bool roomDoesNotExist(int roomToRemove);
    void removeAllLinksToRoom(int roomToUnlink);
    void renumberLinkedRoomsAfterErase(int erasedRoom);
};

因为它可能是相关的,所以我包括了我的整个 Room 类:

#include "Wall.h"

#include <vector>
#include <algorithm>
#include <string>

#include "exceptions/houseException.h"

using namespace std;

class Room {
    public:
    float setPointDegF;
    vector<Wall> walls;  //TODO consider making walls protected / private

    private:
    string roomName;
    vector<int> linkedRooms;
    float storedTemperature;
    float storedHumidity;

    //member functions
    void linkToRoom(int roomToLink);
    void unlinkFromRoom(int roomToUnlink);

    void removeAllLinksToRoom(int roomToUnlink);
    void renumberLinkedRoomsAfterErase(int erasedRoom);

public:
    //friends
    friend class House;

    //member functions
    void addWalls(unsigned int numWallsToAdd=1);
    void removeWall(unsigned int wallToRemove);

    //Sensor Functions
    void readSensorTemperature();
    void readSensorHumidity();

    void temperature();
    void humidity();

    //constuctors / destructors
    Room();
    virtual ~Room();
//STL linked list overload operators =, ==, and <
    Room &operator=(const Room &rhs);
    int operator==(const Room &rhs) const;
    int operator<(const Room &rhs) const;
private:
    void getAttachedRooms(Wall& tempWall);

    bool wallDoesNotExist(unsigned int wallToRemove);
    bool roomLinked(int roomToLink);
    bool roomNotLinked(int roomToLink);

    vector<int>::iterator findRoom(int roomToFind);
    vector<int>::iterator findInsertionPoint(int roomToInsert);


};

【问题讨论】:

  • 你的向量包含什么,传递的索引是什么?
  • “我知道你们中的许多人可能会问我为什么不使用列表” -- 不,我们没有。链表的用途很少而且相差甚远,而且它们在 CS 课程中被过分强调了。
  • 很难回答,因为缺少很多代码。您确实意识到 rooms.erase(roomIterator); 会将 roomToRemove 之后的所有元素向左移动。因此,如果 roomToRemove 为 4,那么在 rooms[5] 中的内容现在在 room[4] 中。
  • @WhozCraig:确实,我一定是暂时失明了。
  • @n.m.噗。没有一天过去,我在某种程度上没有遭受这种痛苦。

标签: c++ stl stdvector


【解决方案1】:

rooms.erase(roomIterator) 将删除位置roomIterator 处的元素。如果要删除从开头到roomToRemove的所有元素,请使用rooms.erase(rooms.begin(), rooms.begin()+roomToRemove)rooms.erase(rooms.begin(), roomIterator)

【讨论】:

  • 我将建议该函数的名称是一个强有力的指标,他试图从列表中删除 single 房间。
  • @WhozCraig 是的,你可能是对的。但是当我读到I cannot get any element other than the last to erase with this code. 时——我解释说他试图删除多个元素,或者至少不仅仅是最后一个元素......我可能错了。
  • 抱歉不清楚。我只是想删除向量容器中的单个元素。
【解决方案2】:

n.m.在我的问题下方的 cmets 中回答了这个问题,但为了清楚起见,我在这里重新输入:

另外,Room 类是否有赋值运算符和副本 构造函数定义正确? ——n.m.

答案:否。一个显式的 Room 类分配运算符导致了问题。

我试图重载默认赋值运算符,但失败了 悲惨地。当我注释掉该代码并使用隐式 &= 接线员,生活很好。问题解决了。 -neghzero

【讨论】:

    猜你喜欢
    • 2013-08-20
    • 2012-02-25
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多