Копирование массивов объектов

0

Это то, чего я раньше не делал и хочу знать, какая должна быть правильная методология

Если у вас есть тривиальный объект, например:

struct simple_object {
    int i;
};

И в вашем приложении вы создали массив этих объектов формы:

simple_object *array = new simple_object[10];

Я знаю, что поведение по умолчанию c++ заключается в распределении массива и вызове конструктора по умолчанию этого класса для каждого объекта, и аналогичным образом деструктор будет вызываться для каждого из delete [] array.

Вопрос возникает, когда вы хотите увеличить размер массива. Например, если вы хотите удвоить размер массива, вы можете сделать что-то вроде:

simple_object *temp = new simple_object[20];
memcpy(temp, array, sizeof (simple_object) * 10);
delete [] array;
array = temp;

Но я думаю, что это опасно и, вероятно, даже не будет работать (вероятно, будут какие-то конфликты в деструкторе более сложного объекта). Другой вариант:

simple_object *temp = new simple_object[20];
for (i to 10)
{
   temp[i] = array[i];
}
delete [] array;
array = temp;

Таким образом, каждый элемент в массиве по умолчанию сконструирован, и конструктор копирования для каждого объекта вызывается непосредственно. Является ли это правильным способом копирования массивов объектов или есть другие более стандартные способы сделать это?

Я знаю, что стандартным вариантом будет использование вектора и использование его возможностей для изменения размера, но вместо ответа на шаблонный шаблон я хотел бы лучше понять, какова должна быть правильная операция для копирования массивов объектов

  • 2
    Возможно, вы ищете std::copy
  • 0
    В вашем последнем примере конструктор копирования не вызывается, оператор копирования-назначения. Поскольку вы удаляете исходный массив после копирования, std::move может пригодиться.
Теги:
object
arrays

2 ответа

1
Лучший ответ

Если вы настаиваете на том, чтобы делать это вообще, вы должны, вероятно, сделать так, как это делает std::vector. Он выделяет необработанную память operator new (через распределитель). Затем он использует placement new для создания элементов в этой памяти.

Когда ему нужно переместить объект, он будет использовать назначение/построение перемещения по предпочтению. Если это не доступно, оно копирует, а затем уничтожает старые.

В любом случае он не будет создавать объекты по умолчанию, такие как массив.

0

Работая с (динамической длиной) необработанными массивами, вы можете использовать std::copy для копирования элементов. Это эквивалентно использованию цикла, за исключением того, что он может быть оптимизирован для случаев, когда он может безопасно вызвать, например, memcpy для выполнения задания. То есть, безопасно и эффективно, где это может быть.

Вы также можете использовать алгоритм std::move для перемещения элементов из массива, который будет удален. Тем не менее я менее уверен в проблемах безопасности исключений, тем не менее, что делать, если возникает исключение, делая переход, скажем, наполовину. Я думаю, было бы довольно сложно оправиться от этого, но я не использовал это, т.е. я не вникал в это, на самом деле, и это просто мое впечатление.

Но гораздо проще просто использовать std::vector вместо необработанных массивов.

Он заботится о управлении памятью и копировании.

Ещё вопросы

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