DebareDaDauntless
DebareDaDauntless

Reputation: 521

Adding something to an array

I have a class, whereby one of its elements is of another class, but is an array

class B
{
public:
    B()             //default
    {
        element = new A [1]; count = 0;
    }

    A add(A place)
    {
        A* newArr;
        newArr = new A [count+1];

        newArr = element;
        newArr[count+1] = place;
        delete element;

        return newArr[count+1];
    }



protected:
    int count;
    A* element;
};

I am trying to use dynamic arrays, where I when adding the element, I make a new array dynamically, initilzed to the size of the old array plus 1, then copy the elements of the old array to the new array, and then delete the old array. But I am unsure of how to modify the array that's already within the class, if that makes sense (Basically what to return in my add method).

Upvotes: 0

Views: 119

Answers (2)

legends2k
legends2k

Reputation: 32884

In C++ there's no notion of resizing arrays once declared. Same goes for dynamic arrays, which can't be resized once allocated. You can, however, create a bigger sized array, copy all elements from the older array to the newer one and delete the old one. This is discouraged and would not be performant.

Using std::vector would allow you to add at will and will also keep track of its size, so you don't need count as part of the class.

class B
{
   // no need to allocate, do add when required i.e. in B::add
   B() : count(), elements() { }

   A add(A place)
   {
      // unnecessarily allocate space again
      A *new_elements = new A[count + 1];

      // do the expensive copy of all the elements
      std::copy(elements + 0, elements + count, new_elements);

      // put the new, last element in
      new_elements[count + 1] = place;

      // delete the old array and put the new one in the member pointer
      delete [] elements;
      elements = new_elements;

      // bunp the counter
      ++count;

      return place;    //redundant; since it was already passed in by the caller, there's no use in return the same back
   }

protected:
   size_t count;
   A *elements;
};

The above code perhaps does what you want but is highly discouraged. Use a vector; you code will simply become

class B
{
    // no need of a constructor since the default one given by the compiler will do, as vectors will get initialized properly by default

    void Add(A place)
    {
         elements.push_back(place);
         // if you need the count
         const size_t count = elements.size();
         // do stuff with count here
    }

    protected:
       std::vector<A> elements;
};

Upvotes: 2

Zac Howland
Zac Howland

Reputation: 15872

A more thorough example would be to more closely mimic std::vector:

template<typename T>
class B
{
private: // don't put data under a protected access!
    std::size_t _capacity;
    std::size_t _size;
    T* _elements;

public:
    B() : _capacity(0), _size(0), _elements(nullptr) {}

    // other methods

    void add(const T& t)
    {
        if (_size >= _capacity) // need to resize the array
        {
            _capacity++; // you can make this better by increasing by several at a time
            T* temp = new T[_capacity];
            std::copy(_elements, _elements + _size, temp);
            delete [] _elements;
            _elements = temp;
        }
        _elements[_size++] = t;
    }
};

Upvotes: 0

Related Questions