domingo, 18 de marzo de 2007 17:55
jonas
Coding Horror: Punteros (II)
En esta segunda parte veremos un ejemplo de cómo trabajamos con
punteros en el paradigma de la orientación a objetos, a partir de ahora
denominaré puntero como referencia a un objeto.
En un lenguaje orientado a objetos (el que yo utilizaré será C#)
constantemente trabajamos con referencias pero puede que en muchas ocasiones no
seamos conscientes de ello.
String s1 = "Un string";
String s2 = "Otro
string";
String sRef = s1;
Console.WriteLine(sRef.ToString());
sRef = s2;
Console.WriteLine(sRef.ToString());
Algo básico, en este fragmento de código se puede ver como se
crean dos objetos y una referencia al primero de ellos en la tercera línea de
código. Al mostrar por consola información del objeto que utilizamos como
referencia sRef, la salida será: Un string. La siguiente línea hace que dejemos
de referencia al objeto s1 y que sea s2 el objeto referenciado, entonces la
salida será: Otro string.
Ahora vayamos a algo más sustancial, una buena manera de aprender
como se trabaja el manejo de referencias a objetos es con las listas (o pilas,
colas o similares…). En primer lugar nos crearemos una clase Nodo que contendrá una referencia al
objeto que almacena y otras dos de tipo Nodo a los objetos anterior y siguiente, nodos que formaran parte de la lista. El
código podría ser el siguiente (por simplicidad dejaré a un lado la ocultación
de información):
public class Nodo
{
public Object info;
public Nodo anterior;
public Nodo siguiente;
public Nodo(Object e, Nodo ant, Nodo sig)
{
info = e;
anterior = ant;
siguiente = sig;
}
}
Y ahora la clase para la lista, muy sencillita, con un
constructor y un método para añadir objetos a nuestra lista:
public class DinamicList
{
Nodo
NodoCabeza;
public DinamicList()
{
NodoCabeza = new Nodo(null, null, null);
NodoCabeza.anterior = NodoCabeza;
NodoCabeza.siguiente = NodoCabeza;
}
public void add(Object x)
{
if (x == null) //no se permiten
nulos
throw new ArgumentException();
Nodo nuevo = new Nodo(x,
NodoCabeza, NodoCabeza.siguiente);
NodoCabeza.siguiente.anterior =
nuevo;
NodoCabeza.siguiente = nuevo;
}
//resto del codigo
}
NodoCabeza representa
al primer nodo de nuestra lista y si nos fijamos en el constructor, cuando lo
creamos no hace referencia a ningún objeto, esto es para poder diferenciarlo de
los demás, por eso no se permite almacenar nulos. Lo siguiente es establecer las referencias anterior y siguiente, esto es
lo que ocurriría en las tres líneas de código del constructor de una forma gráfica:

En el método add, lo que hacemos es crear un nuevo nodo que
contiene al objeto x que agregamos a
la lista y actualizamos las referencias para que apunten al sitio correcto,
esto sería lo que ocurriría:

Si añadimos un nuevo objeto y a la lista, veremos como se añade
el objeto al principio de la misma, esto es porque yo lo he preferido hacer
así, pero cada uno podría hacerse una lista como más le guste.

Esto es una lista doblemente enlazada, lo que nos permitiría
movernos hacia adelante y hacia atrás en ella, aparte se podrían crear otras
muchas operaciones sobre la lista como buscar un objeto, borrarlo, concatenar
dos listas… Así que si alguien se anima puede terminar esta lista o empezar la
suya propia, y si no tiene soltura con el manejo de referencias, puede ser una
buena manera de coger destreza. Espero no haber confundido a nadie y que todo quede claro, pero si no es así, pues solo tenéis que decirlo para ver que se puede hacer.