从指针数组中删除一个对象

Posted

技术标签:

【中文标题】从指针数组中删除一个对象【英文标题】:Remove an object from an array of pointers 【发布时间】:2021-03-21 09:44:14 【问题描述】:

我有一个指向 Building 对象的指针数组,如下所示:

class Building 
    int id ;
    int year;
    double price;
    char* adress;
;

我想要做的是通过id 使用operator- 从数组中删除对象,但我真的不知道该怎么做。我的列表类如下所示:

class List 
    Building* buildingList[10];
    static int buildingNr;
    
public:
    
    List operator-(int id) 
        bool exists = false;
        int index;
    
        for(int i = 0; i < buildingNr; i++)
            if (buildingList[i]->getId() == id) 
                exists = true;
                index = i;
                cout << "Building " << index << " was deleted." << endl;
            
    
        if (exists) 
            delete buildingList[index];
            buildingList[index] = buildingList[buildingNr];
            buildingList[buildingNr] = NULL;
            buildingNr--;
        
        else throw - 1;
     
;
    
int List::buildingNr = 0;

我知道有更简单的方法可以做到这一点,比如使用std::vector,但这是一个分配,我必须使用重载的operator- 和一个指针数组以及Building 类来完成它必须看起来像那样。

我也有operator+,它向数组添加一个元素,效果很好。

【问题讨论】:

不是 100% 清楚您的要求,但假设 buildingNr 是列表中的项目数,buildingList[buildingNr] 将超出范围。你可以先buildingNr--buildingList[buildingNr-1] 一些方便的阅读:What are the basic rules and idioms for operator overloading? 其中包含的智慧将帮助您正确掌握操作员的基本形状。 char * 替换为std::string。字符数组很麻烦,尤其是当您必须为结构动态分配它们时。 在重载运算符之前要问自己的一个问题是“这种行为有意义吗?”我怀疑你在这件事上没有太多发言权,因为这是家庭作业,但总是需要考虑。让操作符- 执行查找和删除操作会使源代码更易于阅读吗? 首先我做了一个删除项目的方法,但是老师明确说我们必须重载-操作符才能从列表中删除对象。问题是我不知道如何,因为它是动态分配的。我应该使用 delete/delete[] 还是不使用它们并将指针设置为 NULL? 【参考方案1】:

您的operator- 未正确实现。尽管它找到对象的循环很好,但删除该对象会被破坏。您没有正确更新数组,因为您需要在找到的索引之后向下移动 ALL 的数组元素,而您没有这样做。

另外,请确保您的 List 类正确实现了 Rule of 3/5/0。 operator- 的返回值应该返回一个 new List 对象,因此必须进行 copy。您根本不应该在operator- 中修改this 对象(这是operator-= 要做的工作;请参阅What are the basic rules and idioms for operator overloading?)。

另外,buildingNr 成员不应是 static。这会阻止您一次使用多个 List 对象。

尝试类似的方法:

#include <algorithm>

class List 
    Building* buildingList[10];
    int buildingNr;
    
public:
    
    List() : buildingNr(0) 

    List(const List &src) : buildingNr(src.buildingNr) 
        for(int i = 0; i < buildingNr; ++i) 
            buildingList[i] = new Building;
            buildingList[i]->id = src.buildingList[i]->id;
            buildingList[i]->year = src.buildingList[i]->year;
            buildingList[i]->price = src.buildingList[i]->price;
            buildingList[i]->adress = new char[strlen(src.buildingList[i]->adress)+1);
            strcpy(buildingList[i]->adress, src.buildingList[i]->adress);
        
    

    ~List() 
        for(int i = 0; i < buildingNr; ++i) 
            delete[] buildingList[i]->adress;
            delete buildingList[i];
        
    

    List& operator=(const List &rhs) 
        if (this != &rhs) 
            List tmp(rhs);
            std::swap_ranges(buildingList, buildingList+10, tmp.buildingList);
            std::swap(buildingNr, tmp.buildingNr);
        
        return *this;
    

    List& operator-=(int id)     
        for(int i = 0; i < buildingNr; ++i) 
            if (buildingList[i]->getId() == id) 
                delete buildingList[i];
                for(int j = i + 1; j < buildingNr; ++j) 
                    buildingList[j - 1] = buildingList[j];
                
                buildingList[buildingNr] = NULL;
                --buildingNr;
                cout << "Building " << i << " was deleted." << endl;
                return *this;
            
        
        throw -1;
     

    ...
;

friend List operator-(List lhs, int id)     
    lhs -= id;
    return lhs;
 

【讨论】:

非常感谢,throw -1 在那里,所以我可以处理异常,以防给定的 id 不存在。

以上是关于从指针数组中删除一个对象的主要内容,如果未能解决你的问题,请参考以下文章

删除指针数组而不删除内存中的指向对象?

从字符串指针数组中删除一个元素

如何通过指针从数组中删除元素

无法分配给 C++ 中的指针数组

从读取到对象指针数组的文件中获取段错误?

访问指针数组/通过另一个指针并删除数组中的单个元素而不删除第一个指针或整个数组