IronRabbit
IronRabbit

Reputation: 185

Remove object from an array in C++?

Here's a simplified sample of my code : The .h

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

private:
    Employees *listEmployees;
};

The .cpp

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

I would like to remove an Employee stored in my array. I tried to use :

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

I didn't find satisfying solution on the web. Also, I'm not very familiar with pointer and reference, maybe the error cames from this. Thanks.

EDIT : I'm NOT allowed to use vectors, I must use arrays.

EDIT2 : Thanks for your answer. Here's the solution I used :

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

Where indexEmp is the index of the employee I want to remove.

Upvotes: 3

Views: 12531

Answers (6)

Aamir Ali
Aamir Ali

Reputation: 1

i've done an other version of it which i feel is better sharing with you with this programme we can delete and shift element position in an array using C++:

#include<iostream>
using namespace std;
int a[5];
int found = 0;  
//to get data
int getdata(){
cout<<"\nEnter data in 5 arrays: ";
for(int i = 0; i<5; i++)
{
    cin>>a[i];
}   
}
//to show data
void showdata(){
for(int i = 0; i<5; i++)
{
    cout<<"\na["<<i<<"] = "<<a[i];
}       
}

//for removing and replacing index's
void rerange()
{
    int elloc;
    cout<<"\nWhich element do you want to remove please enter index: ";
    cin>>elloc;
for(int i = 0; i<5; i++)
if(a[elloc] == a[i])
{
    for(int i = elloc; i<5; i++)
    {
        a[i] = a[i+1];
    }
    found++;
}
}

int main()
{
    getdata();
    showdata();
    rerange();
    if(found == 0)
    cout<<"Element not found";
    else
    showdata();
    return 0;
}    

Upvotes: -1

Ziezi
Ziezi

Reputation: 6467

You could just assign an invalid value to the element you want to delete and then elements with this invalid or default value could be regarded as uninitialized or valid to be overwritten.

For example the remove function could be:

void removeEmployee(int index) {

    Employees default_val = NIL_emp;

    listEmployees[index] = defaul_val;     
}

Upvotes: 1

TheUndeadFish
TheUndeadFish

Reputation: 8171

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

This can't work because you can only delete via pointers, but listEmployee[index] is not a pointer (it's direct access to an instance).

Furthermore, new and delete must be balanced. You can only delete what was allocated via new. And only delete[] what was allocated by new[]. So since your listEmployees came from a new[] allocation, then the only valid deallocation action is a delete[] on the listEmployees itself.

In other words, you can't delete an element out of the middle of an array. You can only dispose of the entire array at once.

As others have suggested, vector and such are great to use instead of raw arrays. But it sounds like this is probably a homework problem or some other case where the easy options have been ruled out.

In that case, here are two possibilities:

1) Allocate a second array of Employees sized one less than the original. Then sequentially copy over all of the ones that are supposed to be kept, and excluding the one to be removed. Then deallocate the original array and assign the new array to listEmployees.

2) Starting with the one to be removed, take the next entry in the array and assign it to that one. The move ahead by one and do the same thing again. Keep doing that until the end of the array. The intent is to shift all the others down by one, overwriting the one you wanted to remove. The last element of the array is just left hanging around. If it has any kind of method to clear out its values, then that could be used. Presumably you also have some kind of count of the number of element in the array which is getting updated, thus nothing will try to access that dead entry on the end. So effectively is entry in the middle is removed, but without needing another array allocation.

Upvotes: 1

youssef
youssef

Reputation: 623

Just for more help:

look to this old example from "Thinking in c++ vol 1 page 588" it is very useful to make a kind of dynamic and resizable array from scratch using pointers to your object eg; new Employee.

note : you need to remove #include require.h and add a similar code using if. in addition you need to look to the header "PStash" in the book. Have a look to this topic it's very useful to answer your question specially remove() and inflate() functions implementations.

This example use void * pointers, when you get your pointer you can cast back to you object eg, Embloyee

if you don't like to use void you can make it in templated class and avoid cast stuff

//: 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
} ///:~

Upvotes: 0

Miki
Miki

Reputation: 41765

An alternative approach would be to have an array of bool the same length of Employess to keep track if the object at a specific position is valid or not.

When you add an element, you set the corresponding value in the array, when you remove it, you reset the corresponding value.

When you access your employees, you should also check if it's valid or not.. etc...

It's a lot more work than using a std::vector, which should be your first choice.

Upvotes: 4

templatetypedef
templatetypedef

Reputation: 372814

There is no built-in way to remove an element from a C++ array. Arrays always have fixed size, so you can't add or remove elements.

You do have some other options. For example, you could use the std::vector type, which acts like an array but lets you add and remove elements. Alternatively, if you just need to store elements in some order and don't care what the order is, try using std::unordered_map or std::map.

Hope this helps!

Upvotes: 3

Related Questions