Почему бы не поднять 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);