Это место размещения новое.
Хотя вы не обычно используете его с целыми типами.
Обычно он используется для создания буфера, в который вы затем встраиваете другие типы.
// Allocate a buffer with enough room for two T objects.
char* buffer = new char[sizeof(T) * 2];
// Allocate a T in slot zero
T* t1 = new (buffer + 0 * sizeof(T)) T("Zero");
// Allocate a T in slot one
T* t2 = new (buffer + 1 * sizeof(T)) T("One");
Thats the basics.
Но помните, что объекты, выделенные с размещением нового , не могут быть удалены delete
.. Это связано с тем, что delete
пытается восстановить память, выделенную new
(а также вызвать деструктор). Поэтому, чтобы правильно использовать эти объекты, вы должны вручную вызвать там деструктор.
t1->~T();
t2->~T();
Не забудьте удалить исходный буфер.
delete [] buffer;
Несколько предостережений:
Люди часто видят, что буфер может быть реализован в стек и, таким образом, автоматически освобождается
char buffer[sizeof(T) * 2];
К сожалению, это может быть технически ОК (Компилируется). Но не гарантируется работа, так как память буфера может быть не правильно выровнена для размещения Т внутри. Таким образом, вы должны динамически распределять буфер (с помощью новых gurantees, чтобы память была правильно выровнена для любого объекта выделенного размера (таким образом, по расширению он также выравнивается для любого размера, меньшего размера, чем размер, выделенный). Легкий способ обойти эта проблема заключается в использовании зОго :: вектора
std::vector<char> buffer(sizeof(T) * 2);
T* t1 = new (&buffer[0] + 0 * sizeof(T)) T("Zero");
T* t2 = new (&buffer[0] + 1 * sizeof(T)) T("One");
Другое использование размещения нового, это сбросить объект
Я видел это сделать, но я предпочитаю использовать более стандартный оператор присваивания:.
T obj1("Plop");
obj1 = T("Another Plop");
// Can be done like this:
T obj1("Plop");
obj1.~T();
new (&obj1) T("Another Plop"); // Seems excessive to me. But can be us-full
// in some extreme situations.
Помните, если вы используете метод сброса, вы должны сначала уничтожить старый объект (или объект может не правильно вести себя).
Примечание: Размещение не обычно используется с int (поскольку оно не имеет преимущества (int не имеет конструктора)). –
@Martin: Хотя 'new (x) int()' будет отличаться и может использоваться через шаблон. Всегда использовать parens, даже с новым [], является хорошей идеей. – 2010-10-20 14:39:10
Ссылка на другой вопрос, где вы видели это, может быть полезна. – 2010-10-20 14:42:32