elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Ingresar Registrarse
28 Agosto 2008, 18:06  



+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderador: ®®)
| | |-+  Introducción al curso de POO programacion orientada a objetos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Imprimir
Autor Tema: Introducción al curso de POO programacion orientada a objetos  (Leído 240 veces)
fiisi

Desconectado Desconectado

Mensajes: 17


Ver Perfil
Introducción al curso de POO programacion orientada a objetos
« en: 05 Mayo 2008, 23:45 »

Bienvenidos a otro curso más de ksdepor by fiisi. Esta vez le ha tocado el turno a la tan traida y llevada POO, o lo que es lo mismo, a la Programación Orientada a Objetos.
El por qué de este curso se debe a varias razones. La primera de todas a que siempre había tenido en mente realizar para mi un breve librito en donde explicar de una manera rápida los conceptos de la POO y tener así una referencia rápida un tanto personal. Sin embargo, ahora que estamos embarcados en Macedonia, había pensado realizarlo especialmente para la revista y con un caracter mucho más abierto, para que sirviera a los no iniciados también.

Antes de pasaros a mostrar los capítulos que he diseñado para el curso, os voy avisar que, tal y como reza el título del curso, se utilizará el lenguaje C++ para mostrar todos los ejemplos. El por qué es bien sencillo, el C++ es el lenguaje más extendido hoy en día para la realización de programas orientados a objetos de temática general. Pese a que el C++ no es un lenguaje orientado a objetos puro, sí que incluye características muy poderosas del mismo y que nos serán de gran ayuda a la hora de realizar nuestros programas. Por supuesto, no voy a hacer una enseñanza del C, es decir, para seguir este curso has de saber programar en C tradicional, ya que, como veréis el C++ viene a ser un superconjunto del C, lo único que cambia es la metodología que utilizaremos, esto es, la POO frente a la metodología estructurada y alguna que otra novedad que incluye el C++ frente al C para poder llevar a buen puerto la ya citada metodología orientada a objetos.

Creo que hasta aquí he dejado más o menos claro cuales van a ser las exijencias del curso, ahora os voy a plasmar un pequeño boceto de los capítulos que tengo en mente hacer, ahí van:


Fundamentos de la POO.
Novedades del C++ frente al C.
La piedra angular del C++; las clases
Aprovechémonos de la POO; la jerarquía de clases y la herencia.
Hagamos código más inteligente; polimorfismo y funciones virtuales.
Utilizando la sobrecarga.
La utilidad de las variables y funciones estáticas.
Las funciones amigas.
Las ventajas de new y delete.
Por qué la POO?
Seguro que muchos de vosotros os habreis preguntado unas cuantas veces qué es eso de la programación orientada a objetos, por qué todo el mundo no hace más que hablar de ella como la salvación de la ingeniería del software moderno, etc. Bien, la POO supone, bajo mi punto de vista, el único camino posible a seguir para la realización de programas en la actualidad. Para poder llegar a tal conclusión tan sólo debeís de fijaros en los requisitos que exije la realización de un proyecto de software en la actualidad.
Por un lado están las ingentes cantidades de información a tratar en todos ellos, por otro lado, el equipo de personas que intervienen es bastante numeroso y todos deben de poder utilizar el código que, el resto de miembros del equipo, han realizado sin tener que complicarse la vida. En tercer lugar, los programas actuales ocupan miles de líneas, con lo que no se puede programar a la ligera, hay que seguir unas reglas muy estrictas, que nos permitan construir programas robustos en cuanto al uso de sus estructuras de datos. Otro de los aspectos que hay que tener en cuenta es el de reutilización, cualquier programa ha de estar lo suficientemente bien diseñado para que las partes básicas del mismo puedan servir en la realización y construcción de otros, ya que no nos podemos permitir el "lujo" de estar perdiendo tiempo construyendo una y otra vez las mismas cosas. Hay que aprovecharse de código que ya está hecho.

Hasta aquí os he citado algunas de las características que exijen los proyectos de software de la actualidad. Negar alguna de ellas no es más que engañarse. Atrás quedaron los felices días en los que un programador podía abarcar un proyecto de software. El ejemplo más claro lo teneís en el campo de la programación de juegos. Antes bastaba con un programador, un grafista y ocasionalmente un músico para producir un sensacional juego, sin embargo, ahora para realizar un juego son necesario varios programadores que han de estar colaborando contínuamente, amén del resto de artistas que han de participar en la creación de la obra. Es por ello que no se puede acudir a la programación tradicional para la construcción de programas en la actualidad, ya que esta, no se diseño para dar soporte a grandes desarrollos de software con continuas actualizaciones y con multitud de equipos de desarrollo destinados a un campo específico del proyecto.



Y...¿por dónde van los tiros?
Vereis, la POO se basa en utilizar estructuras de datos en las que, tanto las variables como las funciones que manipulan dichas variables se encuentran unidas. Tan sólo teneis que imaginaros la definción de una estructura en C (struct). Todos sabéis que en las estructuras sólo es posible meter distintos campos que no son más que variables. Así podéis construir una estructura que tenga un campo de tipo entero (int) otro que sea de tipo caracter (char), arrays de un determinado tipo de dato, etc. Por otro lado, están las funciones que tratan a dichas estructuras de datos. En todo momento son "externas", esto es, cualquier funcion PUEDE (si cumple unas características obvias) acceder a un campo de una estructura y trabajar con él.
Pues bien, ahora imaginaros que teneis una estructura en la que están metidos no sólo los campos de variables de toda la vida, sino que, además, están metidas, también, las funciones para manipularlas, de tal modo que, sólo esas funciones que se encuentran metidas en la estructura, pueden manipular esas variables que, también, se encuentran en la estructura. ¿Ya os lo habeís imaginado?, si habeis podido pillar la idea, sabed que para poder crear una variable de dichas estructuras debereis de crear un OBJETO a dicha estructura, ¡sí!, los objetos no son más que variables o, mejor dicho, INSTANCIAS, a las estructuras, que a partir de ahora llamaremos CLASES, que poseen tanto variables como funciones para manipular dichas variables.

Bueno, si habeis logrado quedaros con que son los OBJETOS, INSTANCIAS y CLASES, teneis premio, ya que habeis logrado entender lo suficiente como para poder seguir con éxito. Si no has logrado pillar la idea de todo lo puesto más arriba, no te preocupes, se te irán aclarando a lo largo de los capítulos, pero te recomiendo que te vuelvas a leer lo de antes.



Los pilares de la POO
Después de presentaros una idea general de lo que supone la POO frente a la programación estructurada de toda la vida, os voy a comentar los pilares en los que descansa, esto es, las características que la hacen tan potente. Como vereís al acabar de leer este capítulo, la POO posee una serie de características estupendas para poder trabajar en equipo un proyecto de software, además de permitirnos construir programas envidiablemente robustos.



Encapsulación de datos.
La encapsulación de datos, no es más que la idea que expuesta más arriba, esto es, la idea de mezclar las variables y las fuciones que sirven para manipular dichas variables, en una misma estructura de datos.
Por ahora y hasta que no veamos las clases, quedaros con que todo esto se podría lograr, metiendo en una struct tradicional de C un campo destinado a las variables y otro a las funciones. Lógicamente, la posiblidad de meter funciones en la struct se la debemos al C++.
La encapsulación de datos, es fundamental en la POO, ya que nos permite construir objetos que, como ya se citó más arriba, no son más que instancias (o variables hablando mal) a dichas struct. Las ventajas que reporta la encapsulación de datos son estupendas, ya que nos permiten crear variables totalmente protegidas de posibles efectos no deseados, como cambio de valor por descuido o efectos laterales gracias a tener unas fuciones que se encargan de realizar todas las operaciones sobre ellas, es decir, no penseis que si os construis un objeto con sus propias variables vais a dar vosotros el valor a la variable directamente como se ha hecho toda la vida (que también se puede hacer). Lo que hareis será llamar a una función que lo único que que haréis será realizar dicha asignación.
Seguro que ahora mismo estais pensando que hacer eso es una estupidez, ¿para qué construir una función que haga, por ejemplo, a=b cuando yo mismo lo puedo hacer directamente?, la respuesta es bien sencilla, porque, precisamente en eso consiste la POO; al hacer eso estás ocultando información y evitando que tus variables puedan tomar valores no deseados, limando, en gran medida, fallos de paso de valores a las variables, tan comunes en la programación tradicional.
Pese a que todo esto es lo ideal, no os "asusteis". Como ya veremos, también podemos acceder a las variables que tengamos directamente, sin tener que llamar a una función que se encarge de ello, pero, como ya he intentado recalcar, esto se debe de evitar siempre.



Herencia
La herencia es otro de los pilares sobre los que descansa la POO. Gracias a la herencia, podemos hacer que todas las clases que tengamos, o las que nos interesen, puedan estar conectadas entre sí, aprovechando, unas de otras, diversas características básicas.
La idea de la herencia parte de poder tener un diseño en el que todo se vaya descomponiendo en módulos o problemas que van de lo más general a lo más específico y que a su vez, estén conectados entre sí. Quizás, este concepto va a quedar mejor explicado si se utiliza un ejemplo, así que vamos alla.

Imaginaros que se quiere construir una aplicación sobre las clases coche_turismo y coche_formula1. Para hacer esto mediante POO, tenemos 2 opciones, no utilizar la herencia o utilizarla. En caso de no utilizarla, bastaría con construir los objetos que de cada uno de los vehículos terrestres coche_turismo y coche_formula1, sin embargo, pese a que esta solución es válida, es bastante mala a la hora de utilizar las posiblidades que nos ofrece la POO, ya que se da pie a utilizar la herencia y no la utilizamos.
Fijémonos que tanto el coche_turismo como la coche_formula1 son vehículos terrestres y como tales tienen unas cosas en comunes y otras que no lo son. ¿Por qué no construir una clase que contenga aquellas variables o atributos comunes para que sean heredados por las clases coche_turismo y coche_fórmula1?. Esta es la solución más lógica, ya que, además de permitir un ahorro de memoria, clarifica todo de una forma bastante aguda.
Por todo esto, lo más lógico sería consturir una clase general que tuviera los atributos o variables acerca del tipo de ruedas, velocidad y tipo de motor. Esta claro que cualquier coche ya sea un turismo o de carreras disfruta de esos datos. Por otro lado, también habrá datos que serán específicos de la clase coche_turismo y de la clase coche_formula1, es decir, que habrá datos que pueda tener uno y no los tenga el otro. El caso más claro es el de pasajeros. Mientras un turismo puede llevar pasajeros, un coche de fórmula 1 no puede llevar pasajeros (a parte del conductor, claro), es por esto, que podríamos meter, y así hemos hecho, una variable de ese tipo en la clase coche_turismo.
Como todo esto de la herencia queda mejor con un gráfico ahí va lo que os quiero decir mediante el ejemplo descrito:







En el ejemplo de arriba sólo he tratado para un par de clases pero, como veremos en sucesivos capítulos, la herencia nos permitírá construir perfectas jerarquías de clases que nos ayudarán a partir de una idea general y llegar a algo concreto y de fácil tratamiento.



Pese a que la POO descansa sobre otros importantes pilares, quizás será demasiado prematuro hablaros de ellos ahora, lo importante es que se vaya cogiendo una idea general con lo visto en este capítulo. Saber que es un objeto y que una clase, así como las características y ventajas que aporta una encapsulación de datos y funciones junto a la posiblidad de desglosar nuestros problemas a modo de jerarquías mediante herencias, son cosas suficientes como para ir haciendose una idea de los mecanismos de la POO.
En los sucesivos capítulos, ya nos meteremos "más a fondo" y pondremos listados y ejemplos en código C++.


Novedades del C++ frente al C.
Este capítulo va a estar dedicado a ver alguno de los campos que amplía el lenguaje C++ frente al C. De todos es sabido que, el C++, es una ampliación al C no sólo por la nueva metodología que incorpora sino por una serie de características que nos van a permitir programar de un modo mucho más cómodo y potente. Pese a que en el capítulo actual no vamos a ver todas las características, sí que vamos a "abordar" la primera mitad. La otra, se la voy a reservar a todo lo que significa el uso de las clases en C++ cómo forma o camino para entrar "de lleno" en la programación orientada a objetos. Sin más preámbulos, comenzamos a meter "caña" a la primera de las novedades.


Las primeras novedades y ampliaciones.


Como citaba al comienzo, en este capítulo no vamos a hacer el estudio del tipo de datos clase pues, a todas luces, merece un estudio en exclusiva dada su gran importancia en lo que es la POO en C++. De todos modos, lo que sí vamos a hacer va a ser ver dos especificadores de tipo que vienen del C y han sido ampliados en el C++, esto es, vamos a ver el tipo de datos enum y struct. Después de que entendamos cómo funcionan las novedades en los anteriores especificadores, haremos una parada en el tipo de datos referencia pues, veréis, que va a suavizar, en cierto modo, el uso de punteros. Eso sí, antes pasaremos a comentar la utilidad de dos objetos como son cin y cout y, ya al final, os comentaré si no lo habéis descubierto para entonces, una nueva manera de insertar comentarios en nuestros programas.


Para empezar, muchos de vosotros os habréis empezado a preguntar ¿Pero qué demonios son los especificadores de tipo?, bueno, pues todos lo sabéis ya que no son más que las palabras clave con las que definimos los distintos tipos de datos. Así, int es un especificador de tipo que define un entero o, char, un especificador que hace lo propio definiendo un tipo de dato carácter. Pero hay más como ya sabréis, float, double, etc.


Una vez "aclarado" el concepto pasamos a la explicación de enum y struct como ampliaciones a lo que venía con el C, junto con la explicación dedicada a las variables de tipo referencia.


Una leve, pero interesante, mejora en enum.


Como seguro que muchos de vosotros no habéis utilizado mucho este tipo de datos en C, voy a realizar un breve recordatorio de su utilidad. Las constantes enumeradas o definición de un tipo enumerado consiste en la definición de un nuevo tipo de datos cuyo rango de valores se define, a su vez, por medio de una lista de constantes, es decir:



enum boolean(FALSE, TRUE);
enum semana (LUNES=1, MARTES, MIERCOLES, JUEVES,
             VIERNES, SABADO, DOMINGO);
enum salidaprintf(TABULADOR ='\t', NUEVA_LINEA='\n');

 


Recodaréis que, además, las constantes enumeradas toman como valores por defecto 0,1.... a no ser que nosotros indiquemos lo contrario, como podéis ver en el ejemplo con los días de la semana en los cuales además de hacer que se empiece en 1, el resto de los valores se van a ir asignando de forma automática.

Pues bien, en C++, la palabra clave enum se va a ver incrementada en flexibilidad pues pasa a ser un especificador de tipo real.

Ya se que para muchos esto no puede tener gran "significado", pero tenéis que tener en cuenta que las constantes enumeradas, o lo que es lo mismo enum, puede considerarse como una seria alternativa a las macros definidas con #define y además, podemos utilizar en C++ el especificador sabiendo que es de tipo real. Nuestras posibilidades se ven incrementadas notablemente.


Ampliaciones importantes en struct


De todos es sabido que las estructuras (struct) tienen una importancia vital en la programación pues nos permiten construir complejas "aglutinaciones" de datos que nos van a permitir, después, trabajar con "tablas de datos" distintas de un modo fácil y directo.

Cuando utilizábamos las estructuras en C, no estábamos utilizando un tipo de datos completo, es decir, cuando definimos algo así en C



struct Guerrero {
   char *nombre;
   int fuerza;
   int resistencia;
   int experiencia;
int edad;
};

 


y queríamos crear alguna variable de tipo Guerrero, teníamos dos opciones. Una de ellas era definir la variable de este modo:



struct Guerrero jugador1;

 


y la otra, la final de la estructura poniendo el nombre de las variables en la misma definición, es decir:



struct Guerrero {
   char *nombre;
   int fuerza;
   int resistencia;
   int experiencia;
int edad;
} jugador1;

 


En ambos casos, teníamos una variable de tipo Guerrero que era, a su vez, de tipo estructura. La única pega de todo esto es que no vamos a definir un tipo de datos nuevo en el sentido estricto de la palabra, esto es, siempre definimos estructuras no tipos de datos. Con la llegada del C++, las estructuras pasan a ser tipos de datos completos pudiéndose definir directamente variables del tipo estructura. Volvamos a poner la definición anterior:



struct Guerrero {
   char* nombre;
   int fuerza;
   int resistencia;
   int experiencia;
int edad;
}
 


Ahora, para declarar una variable de tipo Guerrero sólo tenemos que hacer lo siguiente:



Guerrero jugador1;

 


Como podéis comprobar ahora la creación de variables del tipo estructura anterior es idéntica que cuando hacemos lo propio con un especificador entero, carácter, etc. Si recordáis lo más parecido en C lo conseguíamos con la palabra reservada typedef.


Sin embargo, no sólo se ha convertido a struct en un tipo de datos completo sino que, además y como mayor diferencia, las estructuras en C++ pueden contener funciones junto a los datos de toda la vida. Así, ya tenemos que empezar a diferenciar el contenido que se puede encontrar en una estructura, por un lado tendremos las variables de miembro que serán todas aquellas variables contenidas en la estructura y, por otro lado, tendremos las funciones miembro que, al encontrarse más relacionadas con las clases las veremos cuando lleguemos a ellas.


De esta manera, recordad que las estructuras en C++ son un tipo de datos completo y nos permiten definir variables de una manera mucho más óptima. Sabed también que podemos incluir funciones (llamadas funciones de miembro) dentro de las estructuras, esto es, junto a las variables (llamadas variables de miembro) que siempre hemos sabido que debemos definir. De todos modos, como ya dije anteriormente, no estudiaremos por ahora las capacidades derivadas de poder utilizar tales funciones incluidas en las estructuras. Por ahora, basta con conocer, por encima, las novedades.


Por si alguno se lo estaba preguntando, el acceso a las estructuras sigue siendo el mismo, esto es, utilizando el punto (.). En el caso de que tengamos punteros a estructuras, podremos utilizar la flecha de toda la vida, (->).


Ya acabando con las estructuras, si os habéis fijado en la última definición que se realizó del tipo de datos Guerrero para mostrar el ejemplo de uso en C++, veréis que la variable nombre es un puntero y que se define con el * después del tipo de variable, esto es, después del char. Esto es así porque es la metodología típica del C++ si bien, los que no queráis utilizarla podéis seguir definiendo las variables como en C, es decir, con el operador unario * justo antes del nombre de la variable.


cout y cin dos novedades muy interesantes.


A la hora de trabajar con C++ la construcción cout << se suele utilizar para la salida de datos apartando a un lado las funciones de la familia printf del C tradicional. Debemos de tener claro que cout no es más que un objeto al cual le mandamos la información numérica y de texto mediante el símbolo <<. Esto es así porque en la representación de cout << el operador << está sobrecargado para actuar de tal modo que se escriban en la salida estándar el contenido de cout. En los sucesivos capítulos del curso de C++ se expondrán todos los pormenores de lo que es la sobrecarga de operadores de todos modos y como avance hasta que lleguemos aclarar que gracias a la sobrecarga de operadores nos podemos permitir "personalizar" símbolos de operaciones como son +,-,= y ++ para que se comporten de forma distinta cuando se utilicen con objetos de clases también diferentes, sirva esta breve introducción.


Es fácilmente imaginable que si podemos enviar datos a la salida mediante cout también existirá en C++ un objeto similar pero para realizar entradas. El objeto en cuestión será cin y su funcionamiento será muy sencillo pues sólo deberemos de utilizar el formato explicado más arriba para cout. Es la operación clásica de un scanf. Así, si quisiésemos realizar una petición de una variable entera, por poner un ejemplo, podríamos poner este código (de paso aprovecho y meto un ejemplo con cout):


#include <iostream.h>

// Ejemplo de utilización de cin y cout

void main(void)
{
   int valor;
   
   cout << "\nIntroduce un valor entero";

// equivalente a hacer scanf("%d",&valor);
   cin >> valor;
   cout  << "\nHas introducido
                 el valor " << valor;
}

 

Como podéis observar no hay ningún misterio de utilización de estas dos novedades del C++.
Antes de pasar a las referencias, daros cuenta que para trabajar con cin y cout, debemos de utilizar siempre el archivo de cabecera "iostream.h". Podéis tomároslo por el equivalente a "stdio.h" del C.


Las referencias.


Las referencias son novedades absolutas del C++ (no se encuentran disponibles en C). Una referencia es un nuevo tipo de datos que nos va a permitir utilizar las características de los punteros pero tratándolos como variables ordinarias. Podéis imaginaros una referencia como un "alias" de una variable o, mejor dicho, como la misma variable disponible pero con un nombre distinto. ¿Vaya lío no? ;).

Pasemos a explicar cómo se utilizan las referencias para no armarnos tanto "bollo" en nuestra cabeza "programadora"...


La inicialización de una referencia es bien fácil ya que sólo tendremos que asociar la referencia que deseemos a otra variable que ya esté creada por nosotros. Una vez que hemos realizado tal inicialización, la referencia va a estar continuamente asociada con su variable correspondiente. Cabe añadir que, si quisiéramos hacer que nuestra referencia fuese el "alias" de otra variable o lo que es lo mismo que referenciase a otra variable no podríamos, tendríamos un error de compilación.

La declaración de una referencia es bien sencilla:



// dato es una variable definida por
// nosotros y es de tipo entero.
int dato;

// referenciaDato es la referencia que hemos creado.
int& referenciaDato = dato;

 


Como podéis observar para crear una referencia no necesitamos más que la variable a la que queremos referenciar, que en el ejemplo es dato, junto la referencia en sí que se va a definir con el símbolo &. De este modo, referenciaDato es la referencia o alias de la variable dato.

Una vez hechas las dos operaciones anteriores cualquier cambio que hagamos sobre dato se verá reflejado en referenciaDato y viceversa, es decir, si realizamos una modificación en referenciaDato, esta también se va a ver reflejada en la variable dato.

¡Pongamos un ejemplo de todo esto!.




#include <iostream.h>

void main()
{

      int dato = 50;
      int& refDato = dato;

      cout << ‘\n’;

      cout <<  "La variable dato
               vale " << dato << ’\n’;   

      cout <<  "La variable refDato
           vale " << refDato << ’\n’;

      // multiplicamos la variable
      // dato por 2, ahora dato = 100
     dato *= 2;

      cout <<  "La variable dato
           vale " << dato << ’/n’;   
      cout <<  "La variable refDato
           vale " << refDato << ’\n’;

   // incrementamos el valor de la
   // referenicia, ahora refDato = 101;
   refDato ++;

      cout <<  "La variable dato
     vale " << dato << ’\n’;   
      cout <<  "La variable
     refDato vale " << refDato;   

}

 


Si ejecutáis este programita veréis que la salida que se obtiene sería:



50
50

100
100

101
101




Con lo que deducimos que los cambios efectuados en dato y refDato se ven involucrados. Debéis de saber que tanto dato como refDato comparten la misma dirección de memoria y por eso, cualquier cambio que efectuemos sobre dato afectará a refDato del mismo modo que si lo hiciéramos al revés.


Para cercioraros de que tanto la variable como la referencia poseen la misma dirección tan sólo tenéis que ejecutar este listado que os muestro a continuación y comprobar que la dirección de dato y refDato es la misma.




#include <iostream.h>

void main()
{
      int dato = 50;
      int& refDato = dato;

      cout << ‘\n’ << "La dirección
     de la variable dato es " << &dato << ‘/n’;

      cout << ‘\n’ << "La dirección de la referencia
     refDato es " << &refDato << ‘\n’;
}

 


Si lo ejecutáis veréis que salen los mismos valores.


Una de las cosas que tenemos que tener bien claro es la utilización del operador unario & con una variable y con una referencia. Cuando declaramos una referencia estamos definiendo un tipo de datos que es exclusivo del C++, en este caso, el operador & va junto al tipo de datos que estamos definiendo como referencia así, si nosotros queremos crear una referencia que va a referenciar a una variable de tipo entero pondremos algo como int& referencia.


Otro uso bien distinto es cuando lo que queremos obtener es la dirección en memoria de cierta variable o dato. En este caso tanto en C como en C++ el operador unario & se comporta de igual modo dándonos la dirección en memoria de tal variable o dato. Tan sólo tenéis que ejecutar el último de los listados expuestos el cual nos mostrará, por pantalla, la dirección en memoria de una variable de tipo entero y la de una referencia que tiene con alias precisamente tal variable de tipo entero.


Referencias y punteros.


Todo lo que hacíamos con punteros lo podemos realizar con las referencias de un modo mucho más intuitivo. Pese a que nosotros cuando trabajamos con las referencias lo hacemos como si de otra variable más se tratara, el compilador lo que realmente está haciendo es utilizar esa referencia como un valor asociado a la dirección en memoria de la variable en cuestión, es decir, nosotros utilizamos las referencias como si de otra variable más se tratará mientras que el compilador realmente las utiliza como los tan temidos e importantes punteros del C.


Como lo mejor para ver esto es con un ejemplo ahora os muestro cómo realizar el cambio del valor de una variable local desde una función con C, es decir, con punteros y, después, la versión en C++ utilizando las referencias.



#include <stdio.h>

/* Prototipo de la función para cambiar valor */

void CambiaVble (int *punt);

void main(void)
{
   int vble = 50;
   
   printf("/n El valor de vble es %d",vble);
   CambiaVble (&vble);
   printf("\n El valor de vble es %d",vble);
}

void CambiaVble (int *punt) { *punt = 0; }

 


Esta es la forma tradicional de trabajar en C y la salida debería de ser


El valor de vble es 100
El valor de vble es 0
Pasemos ahora a ver cómo hacer lo mismo pero utilizando referencias.


#include <iostream.h>

/* Prototipo de la función para cambiar valor */

void CambiaVble (int& ref);

void main(void)
{
   int vble = 50;
   
   cout << "\n El valor de vble es " << vble;
   CambiaVble (vble);
   cout << "\n El valor de vble es " << vble;
}
void CambiaVble (int& ref) { ref = 0; }

 


 

Si os fijáis bien y lleváis un tiempo trabajando con punteros en C veréis que realmente el utilizar referencias es como utilizar cualquier otro tipo de variable y esto último hace que los "escabrosos" punteros se vuelvan mucho más sencillos de utilizar para el programador.


Estos dos listados lo he realizado pensando en mostrar como ejemplo de comparativa entre punteros y referencias con lo que muy pocas ventajas pueden ser sacadas de ellos. Pese a que su uso es muy recomendado, hay que tener cuidado especialmente cuando uno empieza a codificar un programa de cierta envergadura en el cual, rápidamente comienzan a crecer variables, constantes y demás parámetros que pueden "ocultar" a nuestras referencias.


Cuando trabajábamos en C siempre sabíamos localizar un puntero por el hecho de llevar siempre el operador unario como identificativo frente al resto de variables de nuestra creación. Con todo esto quiero decir que una referencia no tiene que ser identificada utilizando ninguna clase de símbolo especial y que puede ser confundida como una variable más pasando por alto el gran "poder" contenido en ella.


Las referencias, en definitiva, deben de ser utilizadas cuidadosamente procurando en todo lo posible, poner algún comentario explicativo que nos identifique rápidamente que eso a lo que vamos a "tocar" no es una variable como otra cualquiera sino la citada referencia. Estáis avisados, se pueden meter muchas patadas con esto...


Los comentarios en C++


Ya para finalizar este capítulo vamos a echar un vistazo a la novedad referida al formato con el que podemos incluir nuestros comentarios. Como ya habréis podido observar a lo largo de todos los ejemplos incluidos, los comentarios en C++ se van a poner justo después de que pongamos las dos barras invertidas //. Esta forma de poder poner los comentarios nos va a permitir trabajar de una forma mucho más cómoda y rápida para poner nuestras anotaciones. Lógicamente también podemos seguir utilizando las clásicas /* */ para dejar nuestros apuntes en el código.


Y se acabó el capítulo.


Pues sí, ya hemos concluido este segundo capítulo de POO. Hay alguna que otra cosa que me hubiera gustado comentar como era el caso del uso de cualificadores, esto es, const y todas sus aplicaciones así que no os estrañéis si lo meto en un apéndice.

Para la siguiente entrega de Macedonia, espero poder volver con más cosas entre las cuales estará, sin duda, el capítulo sobre las Clases.

En línea
fiisi

Desconectado Desconectado

Mensajes: 17


Ver Perfil
Re: Introducción al curso de POO programacion orientada a objetos
« Respuesta #1 en: 05 Mayo 2008, 23:48 »

creo asi se van a aburrir mejor los voy a dar archivado por es bastante
el tema
para los q cursan  la universidad le va a sevir mucho

en los comienzos de su carrera 

ya se ing informatica ing sistemas y los aficionados
En línea
fiisi

Desconectado Desconectado

Mensajes: 17


Ver Perfil
Re: Introducción al curso de POO programacion orientada a objetos
« Respuesta #2 en: 05 Mayo 2008, 23:57 »

En línea
Páginas: [1] Ir Arriba Imprimir 
Ir a:  





Consolas     La Web de Goku     MilW0rm     MundoDivx

Hispabyte     Truzone     TodoReviews     ZonaPhotoshop

hard-h2o modding    Foros de ayuda    Yashira.org    Videojuegos    indetectables.net   

Noticias Informatica    Seguridad Informática    ADSL    Foros en español    eNYe Sec

Todas las webs afiliadas están libres de publicidad engañosa.

Powered by SMF 1.1.5 | SMF © 2006-2008, Simple Machines LLC