Introducción:
Aunque es un poco al estilo de coña, en realidad es algo que deberías tener
en cuenta, y que no solo es válido para los punteros "puros" (los de C/C++) si
no para cualquier variable que tenga una referencia a un objeto.
Si usas punteros...
Te cuento la historia:
El otro día (el día 10, para ser concretos) estaba revisando los mensajes
recientes de mis foros y estuve respondiendo a unos cuantos (últimamente hay
poca gente que responda a los mensajes, o al menos hay menos que antes,
puede que sea porque los que preguntan parece que quieren que le den todo el
código resuelto en vez de resolverle "una duda", pero eso sería otro tema, y
además más adecuado para mi blog que para este articulo, que si no, va a
parecer que estoy echándole la bronca al que hizo la duda que ha motivado
que escriba esto... ¡jo, como me enrollo! con razón últimamente no escribo
artículos, jejeje).
Como te decía, entre los mensajes que estuve leyendo, porque antes los leo,
me encontré con uno del
foro de C/C++ que decía lo siguiente:
Hola, a ver si me podeis ayudar, tengo un problema con las variables al usar esta funcion o bien al hacerla a mano:
char *var="HOLA MUNDO";
char *varmin;
varmin = var;
printf ("ANTES -> PASADA: %s CONVERTIDA: %s\n", var, varmin);
// Aqui el contenido de las dos variables seria "HOLA MUNDO"
var = strlwr(var);
printf ("PASADA: %s CONVERTIDA: %s\n", var, varmin);
// En cambio aqui el contenido es "hola mundo" en las DOS,
// cuanod en varmin deberia seguir siendo en mayusculas.
Al usar la funcion strlwr o bien hacerme yo una de conversion con tolower tengo el problema de que la variable que le paso cambia a minusculas en todo el programa, cuando lo que necesito es tener un antes y un despues.
A ver si alguien puede ayudarme que ando loco, muchas gracias de antemano.
La cuestión (por si no estás ducho en esto de los punteros), es que al
hacer la asignación:
varmin = var
y estar usando punteros, en realidad estas asignando la misma dirección
de memoria a las dos variables, por tanto, si haces un cambio en una de
ellas también haces el cambio en la otra... pero no por nada mágico, si no
porque ambas variables están apuntando al mismo contenido de la
memoria.
En este caso, la solución estaría en asignar a varmin un
duplicado de lo que tiene la variable var, en C/C++ se
puede hacer por medio de funciones como strdup, y esa fue
la respuesta que le di al que prengunto.
Seguramente "los expertos" dirán que a ellos nunca les ha pasado (ni les
pasará) nunca algo como esto, pero... ahí está para que se aplique el parche
el que quiera... y lo de aplicar el parche no es nada con segundas
intenciones, simplemente es algo que si vas a usar punteros debes tener en
cuenta... es decir, si te metes con los punteros, lo mejor que puedes hacer
es estar bien informado y procurar no olvidar estas cosas...
¿Ocurre esto también en Visual Basic o en cualquier lenguaje de .NET?
Y para aquellos que programan con Visual Basic (cualquier versión, ya sea
o no para punto NET) decirles que tampoco están libres, ya que (a su manera)
pero Visual Basic también usa punteros, y a más de uno le habrá pasado que
al asignar una variable que contiene un objeto de memoria, después hace una
copia (asignando simplemente una variable a otra) y se piensan que tienen
dos objetos independientes, pero no... no es así... en realidad solo tiene
un objeto en memoria, pero mas de una variable que hace "referencia" a ese
objeto... sí, las variables a las que asignamos los objetos por referencia
(casi todo lo que manipulamos en punto NET) en realidad son punteros a esos
objetos.
Un ejemplo para que lo tengas claro.
Nota:
Creo que será mejor explicarlo en otro momento y de forma independiente, ya
que puede que a más de uno también le ocurra con Visual Basic o con C#...
Vale, para que no te quedes con la intriga o por si se me olvida... (que
es lo más probable que ocurra).
Básicamente es que no debes asignar una variable que contenga una
referencia de un objeto a otra variable, al menos si lo que pretendes es
hacer una copia independiente, en ese caso, deberías usar el método
Clone de los objetos o bien crear una copia si la clase no tiene
ese método.
Si tienes esto, puedes comprobar a lo que me refiero:
Dim obj1 As New Cliente
obj1.Nombre = "Antonio"
Dim obj2 As Cliente = obj1
' muestran lo mismo
Console.WriteLine("obj1= {0}, obj2= {1}", obj1.Nombre, obj2.Nombre)
obj2.Nombre = "Juan"
' sigue mostrando lo mismo, pero usando la ultima asignacion
Console.WriteLine("obj1= {0}, obj2= {1}", obj1.Nombre, obj2.Nombre)
Es decir, las dos variables están apuntando a un mismo objeto
del tipo Cliente, por tanto, al cambiar el valor del Nombre en una de esas
variables, también se cambia en el otro...
Espero que te sea de utilidad.
Nos vemos.
Guillermo
P.S.
Esto en realidad no tiene nada que ver en "como hacer algo en punto NET" pero... no sabía donde meterlo, y ya que C# permite el uso de punteros, al
menos si se escribe el código en modo INSEGURO, pues... aquí está para el
que le sirva.
Las palabras clave podrían ser: punteros, pointers, punteros en C, punteros
en C++
P.S.2
En realidad, al intentar
extrapolar el problema a VB me di cuenta de que en realidad esto es muy
útil para todos los que programan, ya sean con punteros directamente o con
los punteros camuflados que hacen "referencia" a objetos...