在C ++中从数组中删除对象?

时间:2015-07-08 23:32:10

标签: c++ arrays

以下是我的代码的简化示例: .h

class Company {
public:
    Company();
    void addEmployee(const Employee &emp);
    void removeEmployee();

private:
    Employees *listEmployees;
};

.cpp

Company::Company(){ listEmployees = new Employees[16]; }
Company::addEmployee(const Employee &emp) {listEmployee[index]=emp;}
Company::removeEmployee(){ ??? }

我想删除存储在我的数组中的Employee。我试着用:

delete listEmployee[index]; //->"cannot delete expression of type 'Employees'
listEmployee[index]=NULL;   //->"no viable overloaded '='"

我在网上找不到令人满意的解决方案。另外,我对指针和引用不太熟悉,也许错误来自于此。 感谢。

编辑:我不允许使用向量,我必须使用数组。

EDIT2:谢谢你的回答。这是我使用的解决方案:

for(int i=indexEmp;i<sizeArray-1;i++){
    listEmployees[i]=listEmployees[i+1];
}

其中indexEmp是我要删除的员工的索引。

5 个答案:

答案 0 :(得分:3)

没有内置方法可以从C ++数组中删除元素。数组总是有固定的大小,因此您无法添加或删除元素。

您还有其他选择。例如,您可以使用std::vector类型,它类似于数组,但允许您添加和删除元素。或者,如果您只需要以某些顺序存储元素而不关心订单是什么,请尝试使用std::unordered_mapstd::map

希望这有帮助!

答案 1 :(得分:3)

另一种方法是使一个bool数组具有相同的Employess长度,以跟踪特定位置的对象是否有效。

添加元素时,在数组中设置相应的值,删除后,重置相应的值。

当您访问您的员工时,您还应该检查它是否有效......等等......

这比使用std::vector要多得多,这应该是你的首选。

答案 2 :(得分:1)

delete listEmployee[index]; //->"cannot delete expression of type 'Employees'

这不起作用,因为您只能通过指针删除,但listEmployee[index]不是指针(它可以直接访问实例)。

此外,必须平衡new和delete。您只能delete通过new分配的内容。只有delete[]new[]分配的内容。因此,由于listEmployees来自new[]分配,因此唯一有效的重新分配操作是delete[]本身的listEmployees

换句话说,您无法删除数组中间的元素。您只能一次处理整个阵列。

正如其他人所建议的那样,vector等很好用而不是原始数组。但听起来这可能是一个家庭作业问题或其他一些简单易用的选择。

在这种情况下,有两种可能性:

1)分配第二个Employees数组,其大小比原始数组少一个。然后依次复制应该保留的所有那些,并排除要删除的那个。然后解除分配原始数组并将新数组分配给listEmployees

2)从要删除的那个开始,获取数组中的下一个条目并将其分配给该数组。前进一步,再做同样的事情。继续这样做直到数组结束。目的是将所有其他人减少一个,覆盖你想要删除的那个。数组的最后一个元素就是四处闲逛。如果它有任何方法来清除它的值,那么可以使用它。据推测,你也可以对数组中元素的数量进行某种计数的更新,因此没有任何东西会尝试在最后访问那个死的条目。所以有效的是中间的条目被删除,但不需要另外的数组分配。

答案 3 :(得分:0)

只是为了获得更多帮助:

  

从“Thinking in c ++ vol 1 page 588”中查看这个旧例子,使用指向对象的指针从头开始创建一种动态且可调整大小的数组是非常有用的。 new Employee.

注意:您需要删除#include require.h并使用if添加类似的代码。另外你需要查看书中的标题“PStash”。看一下这个主题,特别是remove()inflate()函数实现回答你的问题是非常有用的。

此示例使用void *指针,当您获得指针时,可以将其转换回对象,例如Embloyee

如果你不喜欢使用虚空,你可以在templated class中进行,并避免使用施法材料

//: C13:PStash.cpp {O}
// Pointer Stash definitions

#include "PStash.h"
#include "../require.h"
#include <iostream>
#include <cstring> // 'mem' functions

using namespace std;
int PStash::add(void* element) {
  const int inflateSize = 10;
  if(next >= quantity)
    inflate(inflateSize);
  storage[next++] = element;
  return(next - 1); // Index number
}
// No ownership:
PStash::~PStash() {
  for(int i = 0; i < next; i++)
    require(storage[i] == 0,
        "PStash not cleaned up");
  delete []storage;
}
// Operator overloading replacement for fetch
void* PStash::operator[](int index) const {
  require(index >= 0,
      "PStash::operator[] index negative");
  if(index >= next)
    return 0; // To indicate the end
  // Produce pointer to desired element:
  return storage[index];
}
void* PStash::remove(int index) {
  void* v = operator[](index);
  // "Remove" the pointer:
  if(v != 0) storage[index] = 0;
  return v;
}
void PStash::inflate(int increase) {
  const int psz = sizeof(void*);
  void** st = new void*[quantity + increase];
  memset(st, 0, (quantity + increase) * psz);
  memcpy(st, storage, quantity * psz);
  quantity += increase;
  delete []storage; // Old storage
  storage = st; // Point to new memory
} ///:~

答案 4 :(得分:0)

您可以将无效值分配给要删除的元素,然后将具有此无效值或默认值的元素视为未初始化或有效以覆盖。

例如,删除功能可以是:

void removeEmployee(int index) {

    Employees default_val = NIL_emp;

    listEmployees[index] = defaul_val;     
}