2009-06-24 19 views
7

Busco en algún código (Delphi 7) con el siguiente comprobación es en la parte superior de cada llamada a un método para un objeto específico:¿Por qué revisaría Assigned (self) en métodos de objetos?

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

    { Real code for this method} 

supongo que esto me impediría intentar llamar a un método en una puntero de objeto nulo Pero me gustaría obtener una excepción tan pronto como intenté acceder a los datos de los miembros en ese caso de todos modos, ¿verdad?

¿Es este algún tipo de estándar que nunca he visto antes? El objeto en cuestión deriva de TPersistent.

Respuesta

8

Puede llamar a un método de instancia en un puntero nulo, aunque no es el tipo de cosa que desea hacer deliberadamente. Cuando eso sucede, la ejecución continúa bastante feliz hasta que necesita acceder a los datos de la instancia y luego todo se dispara.

En ese caso, la comprobación de nil le alertaría en la parte superior del procedimiento para que pueda hacer algo diferente, como el registro de un seguimiento de la pila. O podrías poner un punto de quiebre en la línea de subida para que puedas bucear y ver qué está sucediendo.

Es decir, es algo que podría hacer si tuviera un error específico que estaba tratando de localizar donde se usaba una referencia nula.

Hacerlo regularmente me parece un olor a código.

4

Existen escenarios de infracción de acceso que pueden llevar a la ejecución de código en la memoria donde Self es nulo. Algunos programadores, en lugar de resolver el problema real, intentan eludir el uso de tales afirmaciones, para evitar corrupciones de algún tipo. Verificaría muy bien si esa Excepción aumenta alguna vez en tiempo de ejecución, si es así, tienes un código defectuoso bajo tus manos.

Puede leer el siguiente artículo sobre el tema: When Self in Nil... You Know You are in Trouble.

Otra posibilidad está relacionada con los eventos, puede leer más aquí, con muchos ejemplos para tales pruebas y explicaciones correspondientes: Multicast Events - Part 2.

+2

No diría que este código de ejemplo evita el problema real en absoluto. Por el contrario, resalta el problema de forma explícita. –

10

Un claro error quejándose de un puntero nulo es mejor que una violación de acceso que no dice cómo sucedió.

+1

+1 para capturar un puntero nulo en lugar de una * posible * violación de acceso. –

+0

Entonces, ¿está diciendo que codifica todos sus objetos de esta manera? –

+0

Es muy difícil que una desreferencia de puntero nulo no se active. Usted no posee la memoria allí abajo. –

1

Y luego siempre existe la posibilidad de que el código no se bloquee cuando se ejecuta con nada. Ejemplo: si no está accediendo a ningún campo del objeto propietario. En ese caso, esta prueba atraparía el problema que de otro modo no se detectaría.

Aún así, eso lleva la programación defensiva al extremo. Nunca (OK, casi nunca, solo cuando estoy buscando wabbits ... errr ... squashing bugs) hago eso.

+0

A pesar de que lo he hecho, no es bueno usar un método que no sea de clase como si fuera un método de clase. –

1

Parece que la intención original de ese método es que se convierta en un método abstracto.

3

Esta es una ocasión que definitivamente debería provocar un bloqueo (es decir, una excepción del sistema operativo como "leer desde la dirección 0x00000000"). Lanzar una excepción de idioma es simplemente redundante (y utilizar EAbstractError aquí no lo hace mejor).

La comprobación de parámetros de entrada válidos no es una tarea factible en un lenguaje inseguro, ya que nunca obtendrá la certeza, y por lo tanto su manejo de parámetros inválidos nunca será consistente. (¿Por qué arrojas una excepción cuando se pasa un puntero nulo, pero no para 0x00000001, que es igual de inválido?). Para una discusión más técnica de esta pregunta, lea el blog de Larry Osterman sobre why not to check for valid pointers.

Se debe tener en cuenta una excepción: en Delphi, se puede llamar al método Free en un puntero nulo, que por supuesto requiere ese tipo de comprobación.

Cuestiones relacionadas