0

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).

7
  • To add to that, I am trying to modify the protected member array of a variable of type "B" in main Commented Oct 13, 2013 at 3:11
  • 7
    can't just use vector? Commented Oct 13, 2013 at 3:11
  • I want to use arrays for this Commented Oct 13, 2013 at 3:15
  • 2
    There's no reason to use naked arrays in modern C++ when you have various containers available. Additionally it's unclear what you're trying to do. Commented Oct 13, 2013 at 3:15
  • 1
    For a start delete element should be delete[] element Commented Oct 13, 2013 at 3:16

2 Answers 2

2

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;
};
Sign up to request clarification or add additional context in comments.

6 Comments

Strictly speaking, this is correct. However, since C++ inherits the C standard library, you can resize memory using realloc: cplusplus.com/reference/cstdlib/realloc (just not memory that was allocated using new).
@ZacHowland: I know, one can realloc but chances of it creating issues are high; if one had a pointer to some inner element, there's no guarentee that it'll be valid of the realloc. Moreover, meddling with low level constructs is needed only if no other solution is available. Otherwise using the standard facilities available will save a lot of time and effort.
I don't disagree. I was just pointing out that it can be done ... whether it should be is an entirely different matter.
Got it. Moreover, I wanted to give the OP a taste of what a reallocation would mean i.e. the expense of copying all elements from on location to another. Of course, using realloc shouldn't do this, since it'd be a memcpy under the hood. Using realloc is risky.
How do you use calloc in C++?. You don't, use vector is the accepted answer :)
|
0

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;
    }
};

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.