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, Таким образом, добавление объекта в контейнер требует, чтобы:

  1. Объект сначала создается с использованием конструктора по умолчанию
  2. Оператор присваивания называется

Сравните это со стандартными контейнерами библиотеки:

  1. Объекты создаются с использованием конструктора копирования (и путем размещения `new')
  2. Нет назначения не требуется.

Еще одно соображение заключается в том, что вы не можете вообще позвонить new Type[x] если Type не имеет доступного конструктора по умолчанию Если вы измените public: в приведенном выше примере private:, вы будете наблюдать это. Все еще возможно создать (пусто) std::vector<Type> тем не менее, и вы все еще можете добавлять объекты в него, пока вы добавляете другой (пригодный для использования) конструктор в Type,

Другие вопросы по тегам