Установка ограничений на перегрузку новых и удаление - PullRequest
2 голосов
/ 24 февраля 2011

Можно ли наложить некоторые ограничения на перегрузку операторов new и delete? Перегруженное новое связано в другом файле с моей тестовой программой.

Сценарий:

if(condition is satisfied)
   call overloaded new
else
   call the actual new defined in new.h

Ответы [ 4 ]

3 голосов
/ 24 февраля 2011

Всегда используйте ваш перегруженный new / delete и проверьте ваше состояние в его реализации.

1 голос
/ 25 февраля 2011

Как только вы замените значение по умолчанию ::operator new(), вы больше не сможете его использовать - оно ушло навсегда. См. Этот вопрос .

Если вы хотите получить эффект оригинала ::operator new(), вам придется переопределить его, что не очень сложно.

0 голосов
/ 25 февраля 2011

Вы можете легко выполнить проверку в вашем перегруженном новом операторе. Обязательно реализуйте все варианты нового оператора (как уже указывал AProgrammer).

Вызов оригинала / нового по умолчанию невозможен, но это не сложно реализовать самостоятельно. Ведь новый только выделяет память, вот и все. Поэтому вместо вызова оригинала / нового по умолчанию вы также можете вызвать malloc, HeapAlloc или любую процедуру выделения памяти, найденную в вашей системе. Обязательно вызовите соответствующий метод освобождения памяти (free, HeapFree, ...) в вашей реализации delete.

Вы не сказали, какое условие вы собираетесь проверить при внедрении нового? Если это «статическое» условие (я имею в виду: всегда давать один и тот же результат во время выполнения вашего приложения), то же самое условие также должно быть добавлено к вашей реализации delete.

Если условие зависит от ситуации и изменяется во время работы приложения, вы должны предусмотреть метод, в котором вы можете узнать, какую реализацию удаления использовать в функции удаления. Вот один из способов сделать следующее:

В вашей реализации нового:

  • выделить на 8 байтов больше, чем требуется (это должно быть 8 байтов для правильного выравнивания)
  • заполните первые 8 байтов идентификатором, чтобы вы могли знать, какую базовую функцию выделения памяти вы использовали
  • добавить 8 байтов к выделенному указателю и вернуть этот

В вашей реализации delete:

  • вычтите 8 байтов предоставленного вам указателя
  • проверьте идентификацию, найденную в этом месте (см. Новую), чтобы увидеть, какую базовую реализацию удаления вы должны назвать
0 голосов
/ 25 февраля 2011

Существует три способа предоставить оператору новый.

  • замена одного или нескольких из четырех операторов по умолчанию без размещения новых,

  • предоставляя перегрузку оператору по умолчанию new (таким образом, с дополнительным параметром, они могут вызываться с синтаксисом размещения new),

  • предоставляя операторам новые члены класса, они будут вызываться только для этого класса и их потомков.

В последних двух случаях можно вызвать один из наиболее известных операторов, новых с синтаксисом:

ptr = ::operator new(sz);
ptr = ::operator new[](sz);
ptr = ::operator new(sz, std::nothrow);
ptr = ::operator new[](sz, std::nothrow);

но если вы заменили их, будет вызвана ваша замена. Вы не можете называть операторов по умолчанию новыми, которые вы заменили (ну, возможно, вы можете, играя специфические для реализации трюки компоновщика, но это выходит за рамки языка).

О замене оператора на новый:

  • Вы должны заменить два оператора новыми и соответствующие два оператора удаления вместе (или один из операторов удаления может быть легко вызван с неожиданным указателем)
  • Вы должны заменить два оператора new [] и соответствующие два оператора delete [] вместе (по той же причине)
  • обратите внимание на то, что возможно с новыми обработчиками, некоторые библиотеки играют с этим.
...