![]() |
(const Value: string) vs (Value: string)
Por qué
Código:
procedure SetText(const Value: string) y no sencillamente Código:
procedure SetText(Value: string); Código:
procedure SetText(var Value: string); ?? |
De la ayuda de Delphi:
Cita:
// Saludos |
Aquí te pongo lo que dice la ayuda de Delphi sobre parámetros constantes:
Cita:
Saludos... Update: Como siempre, Román se me adelantó... :D |
Saludos
Cita:
|
Llegue tarde:(
Saludos |
A ver si puedo explicarlo sencillamente o no
En principio, esos dos compadres son iguales, pero no es lo mismo. En el primero, cuando dentro de SetText intentas hacer una asignación a Value, es decir, del tipo
Aqui delphi en compilación no te deja modificar la variable, porque ha sido pasada con el Const. En este otro caso:
Value, dentro de la funcion, te permite modificarla, pero creo que con esto queda más claro: valor tendrá 'pepe', dentro de la funcion SetText, se le da el valor 'pepe que si que si', pero solo dentro de la funcion SetText, cuando salga, es decir en el showMessage saldrá 'pepe' Obviamente, si ponemos SetText(var Value:String); se modifica el valor, y en el showMessage, saldrá 'pepe que si que si' Por tanto, poner el "Const" es un seguro de vida, si quieres modificar la variable localmente o no. Otra cosa distinta es cuando se pasan objetos:
En este caso se pasa un puntero (de 4 bytes) al objeto, por tanto, todos los objetos se pasan por referencia, da igual si pones const, si no lo pones, o si lo pasas con var. De las 3 formas podrás modificar las propiedades del objeto, el width, height, etc. saludos |
Cita:
saludos |
Cita:
Para empezar está el asunto de la optimización que menciona la ayuda de Delphi en cuanto al uso del const. Por otra parte lo que se pasa como const o var no es el objeto sino la referencia al objeto, y ésta sí que puede cambiarse (o evitar que se haga). Aquí un ejemplo extraído de código de Phil Brown:
Aquí la idea es lo que llaman "lazy construction". Objetos como TOrder pueden tener objetos relacionados como TCustomer. Cuando esto se lee de la base de datos, normalmente conviene cargar el objeto relacionado sólo cuando se le llame. Phil Brown utiliza un método genérico en la clase base para cargar los objetos relacionados de manera que los descendientes simplemente tengan que hacer un moldeo al tipo de datos adecuado. En este método base, GetObject, el campo que respalda la propiedad (FCustomer en el caso de TOrder), aún no ha sido creado la primera vez que se le llama. Y lo que GetObject está cambiando es la referencia al objeto (de hecho está creando una nueva). Para ello fue imprescindible el uso de var en la declaración de GetObject. // Saludos |
Exacto.
No quise profundizar en ese sentido, por eso dije explicitamente que podía modificar sus propiedades ;). Sin duda, el hilo ha quedado mucho más completo ahora. saludos |
A las buenas explicaciones ya dadas quisiera añadir algunos "detalles":
Cuando un parámetro se define con los modificadores "const" o "var", este es pasado "por referencia", es decir, es un puntero a la variable original lo que la función recibe, ocupando solamente 4 bytes de memoria en la pila. En cambio, si una variable de 1000 bytes es pasada sin modificadores (por valor), estos 1000 bytes son copiados en la pila y liberados cuando se sale de la rutina. Esto puede provocar errores de desbordamiento de la pila, por ejemplo, en llamadas recursivas. (Un caso típico es el paso de strings al estilo pascal (string[xx])), Por último, con respecto de: Cita:
¿se entendió la diferencia? |
Gracias a todos por la aclaración; sobre todo a Lepe, que lo ha dejado muy bien explicado :)
|
La franja horaria es GMT +2. Ahora son las 13:09:50. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi