2015-04-24 3 views
3

Где-то я читал, что этот вектор внутренне использует новое размещение для построения объекта. Когда я попытался реализовать подобный контейнер, я обычно в конечном итоге с выделением какРазмещение на C++ new vs copy

_elements = new Type[capacity]

, а затем я добавляю новые объекты, как этот

void append(const T& element) { 
    // reallocation in case if capacity is equal to size 
    _elements[size++] = element; 
} 

Есть ли разница в производительности или другой между этой конструкцией копирование и строительство путем размещения новых?

ответ

9

Есть ли какая-либо работа или другая разница между этой конструкцией путем копирования и строительства путем размещения новых?

Конечно. Если вы построите массив:

_elements = new Type[capacity] 

... тогда элементы массива должны быть инициализированы, до емкости. Это означает, что будет создано несколько объектов типа «по умолчанию». С другой стороны, при использовании нового места размещения вы не инициализируете массив, а просто выделяете пространство и строите объекты по мере необходимости. Это более эффективно и семантически отличается, поскольку начальные объекты не создаются (помните, что их создание может иметь побочные эффекты).

Это может помочь вашему понять думать и делать какие-то эксперименты с типом, который действительно имеет видный побочный эффект в его конструктора по умолчанию:

class Type 
{ 
    public: 
    Type() 
    { 
     cout << "Created Type." << endl; 
    } 
}; 

С выше Type, если вы new Type[3] для Например, вы увидите три сообщения, напечатанные на cout. С другой стороны, если вы создадите std::vector<Type> с емкостью 3, вы не увидите никаких сообщений, напечатанных на cout.

Ваш метод Append:

void append(const T& element) { 
    // reallocation in case if capacity is equal to size 
    _elements[size++] = element; 
} 

Вызов оператора присваивания для T. Поэтому добавление объекта в контейнер требует, чтобы:

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

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

  1. Объекты построены с использованием конструктора копирования (и через размещение «новый»)
  2. Нет как нужно подписаться.

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

+0

Не установлено ли по умолчанию значение '()' after '[capacity]'? –

+0

@AlexanderBily вы также получаете конструкцию по умолчанию, если вы опустите символ '()'. Массив должен содержать объекты указанного типа, поэтому необходимо вызвать конструктор _some_ - и это реальная точка. – davmac

+0

@AlexanderBily Да. Нет. Может быть? [Это сложно] (http://en.cppreference.com/w/cpp/language/initialization). Но если 'Тип' не является встроенным типом, * некоторые * работы будут выполнены, и вы не хотите этого. – Quentin

Смежные вопросы