Компилятор позволяет опускать количество выделяемых элементов в new[]:
char* p = new char[];
Возникает два вопроса:
- сколько памяти выделяется?
- для чего это нужно?
Попытаемся ответить на эти вопросы.
Ответ на первый вопрос - нисколько. И сразу же переходим ко второму вопросу.
Ответ на второй вопрос - это использование уже выделенной памяти для новых объектов.
По сути это особая форма оператора new, называемая placement new. Данный оператор не выделяет память, а получает своим аргументом адрес на уже выделенную каким-либо образом память (например, в стеке или через malloc).
Происходит размещение (инициализация) объекта путем вызова конструктора, и объект создается в памяти по указанному адресу. Часто такой метод применяют, когда у класса нет конструктора по умолчанию и при этом нужно создать массив объектов. Ниже приведён простой пример:
Ответ на второй вопрос - это использование уже выделенной памяти для новых объектов.
По сути это особая форма оператора new, называемая placement new. Данный оператор не выделяет память, а получает своим аргументом адрес на уже выделенную каким-либо образом память (например, в стеке или через malloc).
Происходит размещение (инициализация) объекта путем вызова конструктора, и объект создается в памяти по указанному адресу. Часто такой метод применяют, когда у класса нет конструктора по умолчанию и при этом нужно создать массив объектов. Ниже приведён простой пример:
#include <new>
#include <iostream>
class A
{
private:
int _x;
A() {
std::cout << "A() at " << (void*) this << std::endl;
}
public:
A(int x) {
_x = x;
std::cout << "A(" << x << ") at " << (void*) this << std::endl;
}
~A() {
std::cout << "~A() with _x=" << _x << " at " << (void*) this << std::endl;
}
};
int main()
{
const int n = 3;
// выделить память под A, но не вызывая конструктора
char* memory[ n*sizeof(A) ];
A* placementMemory = static_cast<A*>(static_cast<void*>(memory));
// вызвать конструкторы объектов (без выделения памяти, но с использованием выделенной)
for (int i=0; i<n; i++)
// new (указатель_на_область) вызов_конструктора;
new (placementMemory+i) A(i+3); // конструктор может быть с параметрами или без
// следует вручную вызвать деструкторы
for (int i=0; i<n; i++)
placementMemory[i].~A();
return 0;
}
Результат работы:
Полезно будет почитать http://www2.research.att.com/~bs/bs_faq2.html#placement-delete (Bjarne Stroustrup's C++ Style and Technique FAQ)

Комментариев нет:
Отправить комментарий