C++ размещение нового против копирования назначения
Где-то я читал, что вектор внутренне использует размещение новых для построения объектов. Когда я пытался реализовать подобный контейнер, я обычно получал
_elements = new Type[capacity]
а потом я добавляю новые объекты, как это
void append(const T& element) {
// reallocation in case if capacity is equal to size
_elements[size++] = element;
}
Есть ли какая-либо производительность или другая разница между этой конструкцией путем копирования и конструкцией путем размещения новой?
1 ответ
Есть ли какая-либо производительность или другая разница между этой конструкцией путем копирования и конструкцией путем размещения новой?
Конечно. Если вы создаете массив:
_elements = new Type[capacity]
... тогда элементы массива должны быть инициализированы, вплоть до емкости. Это означает, что будет создано несколько объектов типа "по умолчанию". С другой стороны, при использовании размещения new вы не инициализируете массив, а просто выделяете пространство и создаете объекты по мере необходимости. Это и более эффективно, и семантически отличается, поскольку исходные объекты не создаются (помните, что их создание может иметь побочные эффекты).
Это может помочь вашему пониманию подумать и провести некоторые эксперименты с типом, который действительно имеет заметный побочный эффект в своем конструкторе по умолчанию:
class Type
{
public:
Type()
{
cout << "Created Type." << endl;
}
};
С выше Type
если вы делаете new Type[3]
например, вы увидите три сообщения, напечатанные на cout
, С другой стороны, если вы создаете std::vector<Type>
с вместимостью 3, вы не должны видеть никаких сообщений, напечатанных на cout
,
Ваш метод добавления:
void append(const T& element) {
// reallocation in case if capacity is equal to size
_elements[size++] = element;
}
Вызывает оператор присваивания для T
, Таким образом, добавление объекта в контейнер требует, чтобы:
- Объект сначала создается с использованием конструктора по умолчанию
- Оператор присваивания называется
Сравните это со стандартными контейнерами библиотеки:
- Объекты создаются с использованием конструктора копирования (и путем размещения `new')
- Нет назначения не требуется.
Еще одно соображение заключается в том, что вы не можете вообще позвонить new Type[x]
если Type
не имеет доступного конструктора по умолчанию Если вы измените public:
в приведенном выше примере private:
, вы будете наблюдать это. Все еще возможно создать (пусто) std::vector<Type>
тем не менее, и вы все еще можете добавлять объекты в него, пока вы добавляете другой (пригодный для использования) конструктор в Type
,