Компилятор позволяет опускать количество выделяемых элементов в 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)
Комментариев нет:
Отправить комментарий