Зачем вам проверять Assigned (self) в объектных методах? - PullRequest
8 голосов
/ 25 июня 2009

Я смотрю на некоторый код (Delphi 7) со следующей проверкой в ​​начале каждого вызова метода для определенного объекта:

if not Assigned(self) then
  raise Exception.CreateRes(@sAbstractError);

  { Real code for this method}

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

Это какой-то стандарт, который я никогда раньше не видел? Данный объект происходит от TPersistent.

Ответы [ 6 ]

10 голосов
/ 25 июня 2009

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

9 голосов
/ 25 июня 2009

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

В этом случае проверка на nil предупредит вас в начале процедуры, чтобы вы могли сделать что-то другое, например, запись трассировки стека. Или вы можете поставить точку разрыва на линии поднятия, чтобы вы могли погрузиться и посмотреть, что происходит.

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

Регулярное выполнение этой программы кажется мне запахом кода.

4 голосов
/ 25 июня 2009

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

Вы можете прочитать следующую статью на эту тему: Когда Я в нуле ... Вы знаете, что у вас проблемы .

Другая возможность связана с событиями, вы можете прочитать больше здесь, с большим количеством примеров для таких тестов и соответствующими пояснениями: Multicast Events - Part 2 .

3 голосов
/ 25 июня 2009

Это случай, который обязательно должен привести к сбою (т. Е. Исключение ОС, такое как «чтение с адреса 0x00000000»). Создание языкового исключения просто избыточно (и неправильное использование EAbstractError здесь не делает его лучше).

Проверка на допустимые входные параметры не является выполнимой задачей на небезопасном языке, так как вы никогда не достигнете определенности, и, следовательно, ваша обработка недопустимых параметров никогда не будет последовательной. (Почему вы бросаете исключение, когда передается нулевой указатель, но не для 0x00000001, что так же недопустимо?). Для более технического обсуждения этого вопроса прочитайте блог Ларри Остермана о , почему бы не проверить правильность указателей .

Следует отметить одно исключение: в Delphi метод Free может вызываться по нулевому указателю, что, конечно, требует такой проверки.

1 голос
/ 25 июня 2009

Кажется, первоначальное намерение для этого метода состоит в том, чтобы он стал абстрактным методом.

1 голос
/ 25 июня 2009

И тогда всегда есть вероятность, что код не потерпит крах при работе с nil Self. Пример - если он не обращается ни к каким полям объекта владельца. В этом случае этот тест обнаружит проблему, которая в противном случае была бы незамеченной.

Тем не менее, это доводит оборонительное программирование до крайности. Я никогда (окей, почти никогда - только когда я охотюсь на вобликов ... ошибаюсь ... кашляю) не делаю этого.

...