Добавление чего-либо в массив

0

У меня есть класс, в котором один из его элементов имеет другой класс, но является массивом

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

Я пытаюсь использовать динамические массивы, где я добавляю элемент, я создаю новый массив динамически, инициализируется до размера старого массива плюс 1, а затем копирует элементы старого массива в новый массив, а затем удаляет старый массив. Но я не уверен, как изменить массив, который уже находится внутри класса, если это имеет смысл (в основном, что нужно вернуть в моем методе добавления).

Теги:
arrays

2 ответа

2

В C++ не было объявлено об изменении размера массивов. То же самое касается динамических массивов, которые не могут быть изменены после выделения. Однако вы можете создать массив большего размера, скопировать все элементы из старого массива в новый и удалить старый. Это обескураживает и не будет исполнять.

Использование std::vector позволит вам добавлять по своему желанию, а также отслеживать его размер, поэтому вам не нужно count часть класса.

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 no use in return the same back
   }

protected:
   size_t count;
   A *elements;
};

Вышеприведенный код, возможно, делает то, что вы хотите, но сильно обескуражен. Используйте вектор; вы просто станете

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;
};
  • 0
    Строго говоря, это правильно. Однако, поскольку C ++ наследует стандартную библиотеку C, вы можете изменить размер памяти, используя realloc: cplusplus.com/reference/cstdlib/realloc (только не память, которая была выделена с помощью new ).
  • 0
    @ZacHowland: я знаю, можно перераспределить, но шансы на создание проблем высоки; если бы у кого-то был указатель на какой-то внутренний элемент, нет гарантии, что он будет действительным для realloc. Более того, вмешательство в низкоуровневые конструкции необходимо, только если нет другого решения. В противном случае использование доступных стандартных средств сэкономит много времени и усилий.
Показать ещё 4 комментария
0

Более подробный пример - более точно имитировать 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;
    }
};

Ещё вопросы

Сообщество Overcoder
Наверх
Меню