Волшебство в расстановке новых? - PullRequest
3 голосов
/ 13 ноября 2009

Я играю с динамическим распределением памяти «вручную», и я хотел посмотреть, как размещение new реализовано ребятами из MS, но при отладке я «вмешался», что привело меня к коду:

inline void *__CRTDECL operator new(size_t, void *_Where) _THROW0()
{   // construct array with placement at _Where
return (_Where);
}

Может ли кто-нибудь объяснить мне, как на самом деле этот код помещает мой объект на место, на которое указывает мой указатель, когда все, что я могу видеть в этом коде, это строка с оператором возврата с тем, что я предоставил в качестве аргумента. Я не думаю, что, говоря в комментарии, что я хотел бы, чтобы этот fnc делал, на самом деле достаточно для его работы. Спасибо за любые конструктивные ответы.

Ответы [ 2 ]

14 голосов
/ 13 ноября 2009

Цель operator new состоит только в том, чтобы выделить память для объекта и вернуть указатель на эту память. Когда вы используете размещение new, вы, по сути, говорите компилятору: «Я знаю, что эта память хороша, пропустите выделение и используйте этот указатель для моего объекта». Затем конструктор вашего объекта вызывается с использованием указателя, предоставленного operator new, независимо от того, была ли память выделена или указана с помощью размещения new. operator new само по себе не имеет никакого отношения к тому, как построен ваш объект.

5 голосов
/ 14 ноября 2009

Имейте в виду, что то, что делает new T(...) (называемое "новым выражением"), это две вещи: выделение памяти и инициализация объекта. Вы можете настроить инициализацию, написав конструкторы. Для выделения вы пишете operator new. Таким образом, несмотря на название, operator new делает только одну сторону того, что делает новое выражение.

Помещение new предназначено для помещения объекта в заранее выделенную память. Вы не можете вызывать конструкторы, напрямую передавая заранее выделенную память как указатель this. Единственное, что вы можете сделать, это использовать новое размещение: это превращает распределение в неиспользуемое, оставляя только конструкцию. Это

inline void* operator new(size_t, void *p) throw()
{
  return p;
}

- это просто реализация этого запрета.

...