Это размещение новое.
Хотя вы обычно не используете его с целочисленными типами.
Обычно он используется для создания буфера, в который затем встраиваются другие типы.
// 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");
Это основа.
Но помните, что объекты, размещенные с новым размещением, нельзя удалить оператором delete
. Это связано с тем, что delete
пытается восстановить память, выделенную new
(а также вызывает деструктор). Поэтому, чтобы правильно использовать эти объекты, вы должны вручную вызвать там деструктор.
t1->~T();
t2->~T();
Не забудьте удалить исходный буфер.
delete [] buffer;
Несколько других предостережений:
люди часто видят, что буфер может быть реализован в стеке и, таким образом, автоматически освобождаться.
char buffer[sizeof(T) * 2];
К сожалению, технически это может быть нормально (он компилируется). Но это не гарантирует работу, так как память буфера может быть неправильно выровнена для размещения T внутри. Таким образом, вы должны динамически выделять буфер (используя new, он гарантирует, что память правильно выровнена для любого объекта выделенного размера (таким образом, по расширению она также выравнивается для любого размера, меньшего, чем выделенный размер). Простой способ обойти эта проблема заключается в использовании std::vector
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.
Помните, что если вы используете метод сброса, вы должны сначала уничтожить старый объект (иначе объект может вести себя неправильно).
person
Martin York
schedule
18.10.2010
new(x) int()
будет другим, и его можно будет использовать через шаблон. Всегда использовать круглые скобки, даже с new[], — хорошая идея. - person   schedule 20.10.2010