Почему бы не поднять EInvalidPointer?

Документация Delphi гласит:

Никогда не вызывайте исключение EInvalidPointer напрямую. EInvalidPointer внутренне вызывается диспетчером памяти.

Я пишу пользовательский базовый класс в качестве альтернативы TInterfacedObject следуя реализации RTL как можно ближе, и увидим, например, чтоTInterfacedObjectв RTL реализуетBeforeDestructionкак:

procedure TInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    Error(reInvalidPtr);  
end;

кудаError(reInvalidPtr)повышенияEInvalidPointerс помощью различных методов с единичной областью действия, локальных для RTL.

Если я пишу свой собственный класс, как я должен реализоватьBeforeDestruction? Почему бы не сделать это?:

procedure TMyInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    raise EInvalidPointer.CreateRes(@SInvalidPointer) at ReturnAddress;
end;

Есть ли что-то особенное с глобальным InvalidPointerобъект исключения объявлен вSysUtils? Если это плохая идея, было бы разумно просто вызвать здесь пользовательское исключение?

2 ответа

Решение

Дополняет ответ Давида; что особенного в InvalidPointer, который используется для поднятия EInvalidPointer, вместе с OutOfMemory <-> EOutOfMemory более подробно поясняется в теме документации по их восходящей EHeapException:

EHeapException является классом исключения для ошибок, связанных с выделенной кучей памяти.

Потомки EHeapException - EOutOfMemory и EInvalidPointer - используются для обработки неудачных выделений динамической памяти и недопустимых операций с указателями.

Примечание. Память для этих исключений предварительно выделяется при каждом запуске приложения и остается распределенной до тех пор, пока приложение работает. Никогда не вызывайте EHeapException или его потомков напрямую.

Я предполагаю, что выделение памяти для создания этих ошибок может быть небезопасным, если у вас есть проблемы с памятью: из-за ее отсутствия или возможного повреждения...

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

System.Error(reInvalidPtr);
Другие вопросы по тегам