NOTAS SOBRE TRADUCCION DE CODIGO C++ a JAVA
-------------------------------------------

** Funciones inline

Las funciones inline en C++ no tienen equivalente en Java.  En Java no
distinguimos entre archivo de cabecera y archivo de implementación (.h
y.cc/.cpp, respectivamente), si no que escribimos todo el código en un solo
archivo (.java).  Es decir, a la vez que declaramos los métodos, también
definimos su implementación (cuerpo del método).  Pero esto no significa que
el método sea 'inline'.  El compilador nunca genera código 'inline' para los
métodos, aunque sí lo hace para ciertas constantes estáticas finales ('final
static') con tipos primitivos.  Es la JVM (Java Virtual Machine),
concretamente el compilador JIT, la que en tiempo de ejecución puede decidir
generar código inline para algún método, basándose en complejos análisis del
código a ejecutar.

** Punteros y referencias

Fíjate cómo los punteros a objetos en C++ son equivalentes a las referencias
en Java, aunque sintácticamente se usan de diferente forma: los punteros se
declaran con '*', las referencias no.  Al usar punteros en C++, debes usar
el operador '->' para referirte a las propiedades del objeto al que apunta,
mientras que en Java la sintáxis es usar el operador '.':

C++                         Java
   Clase * unPuntero;           Clase unaReferencia;            // Creamos el puntero/referencia
   unPuntero = new Clase();     unaReferencia = new Clase();    // Creamos el objeto (¡en tiempo de ejecución!)
   unPuntero->atributo = ...    unaReferencia.atributo = ...    // Accedemos a un atributo (siempre que su visibilidad lo permita)
   unPuntero->metodo();         unaReferencia.metodo();         // Llamamos a un método de la clase Clase

** Arrays de tamaño indeterminado

En C++ podemos definir arrays cuya dimensión sólo se conoce en tiempo de
ejecución de esta manera:

	int* array;
	int dimension;

'array' apuntará a una zona de memoria que reservaremos con 'new' y que
tendrá tantas componentes como indique la variable 'dimension'. Fíjate que
necesitamos guardarnos el tamaño del array en la variable 'dimension'
porque, tras reservar memoria, necesitaremos saber cuántas componentes tiene
nuestro array para no pasarnos a la hora de acceder a él y provocar un fallo
de segmento (Segmentation fault).

Supongamos que durante la ejecución del programa necesitamos crear un array
de 10 enteros. Haremos

	dimension = 10;
	array = new int[10];

Y ya podemos usarlo:

	for (int i=0; i<dimension; i++) array[i] = i;

En Java este es el comportamiento por defecto para los arrays: se reserva
memoria en tiempo de ejecución (con 'new'). Un código equivalente al
anterior en Java sería:

declaración:

	int[] array;

creación del array en tiempo de ejecución:

	array = new int[10];

Fíjate en una diferencia importante. No necesitamos la variable 'dimension'.
Los arrays de Java (¡que en realidad son objetos!), tienen un atributo
'length' que se inicializa al tamaño del array y que podemos consultar
siempre que lo necesitemos:

	for (int i=0; i<array.length; i++) array[i] = i;

** Funciones amigas

En Java no existen las funciones amigas.  Para que una clase pueda
acceder a ciertas propiedades de otra, se usa otro mecanismo, conocido como
'visibilidad de paquete', que veremos más adelante.

** Uso de 'const' en C++ ('final' en Java)

En Java no existe 'const', sino 'final' como palabra clave, pero tiene
algunos usos diferentes a los de 'const' en C++.  En el caso particular de
referencias a objetos en C++, como en el caso del constructor de copia de
Coordinate, en Java simplemente indicaremos como argumento una referencia 
de tipo Coordinate:

C++                                 Java
    Coordinate(const Coordinate&);        Coordinate(Coordinate c) {...}

** Operadores sobrecargados en C++

En Java no existe la sobrecarga de operadores, así que los operadores
sobrecargados en C++ (como operator>>) deben implementarse como métodos
normales (en este caso, el operador de salida equivale al método
'toString()').

En los archivos de cabecera de C++.  al declarar un método (función miembro)
no es obligatorio indicar el nombre de los argumentos, como p. ej. en 

int get(int) const;

sino sólo su tipo.  Esto no es posible en Java, ¡ya que a
continuación tenemos que definir el cuerpo del método!

El método 'operator==' equivale aproximadamente al método 'equals() de Java. 
Ambos tienen por misión el decirnos si dos objetos son iguales, es decir,
contienen los mismos valores en los atributos que describen su estado.  La
diferencia radica en el tipo de argumento de ambos métodos.  En la versión
C++, es una referencia a un objeto de la misma clase para la cual definimos
el operador, mientras que en Java se trata de una referencia de tipo
Object.  Esto implica entre otras cosas que, al implementar el método
'equals()', tengamos primero que comprobar si el objeto que nos pasan como
argumento es de la misma clase para la cual definimos equals().

Fíjate que los operadores '+', '-' en C++ tienen dos peculiaridades:

1.  la operación 'a + b' equivale a 'a.operator+(b)' y su resultado es
un nuevo objeto equivalente a la 'suma' de 'a' y 'b'.  

2. Estos operadores tienen asociatividad por la derecha, lo cual significa
que podemos escribir

	a + b - c;

que equivale a

	a.operator+( b.operator-(c) );

de hecho, podríamos escribirlo como en la línea de arriba, pero 'a+b-c'
queda mucho más compacto y es mucho más fácil de entender a primera vista,
que son algunas de las razones por las que se implementó la sobrecarga de operadores en C++.

La expresión de arriba equivale entonces a 

	a + (b - c);

La operación 'b - c' crea un nuevo objeto que es el que se usa como
argumento del operador suma, que a su vez creará un nuevo objeto resultado
de sumarle a 'a' el objeto 'b - c'. Tanto 'a' como 'b' y 'c' quedan
inalterados durante estas operaciones. 

Java no soporta la sobrecarga de operadores. Los métodos equivalentes a la
suma y la resta de C++  en Java (add() y substract() en el diagrama UML de la clase Coordinate), 
se comportan de manera similar a operator+() y operator-(), con una diferencia: la
asociatividad viene dada por el operador '.', cuya asociatividad es de
izquierda a derecha, de manera que escribir en Java

	a.add(b).substract(c);

equivale a escribir en C++

	(a + b) - c;

donde a, b y c son objetos de tipo Coordinate. En resumen, si queremos obtener
asociatividad por la derecha en C++ y Java, escribiríamos

C++:
	a + b - c; // equivale a 'a + (b - c)', o sea, 'a.operator+(b.operator-(c))'

Java:
	a.add(b.substract(c));


** E/S simple: 

El equivalente a las instrucciones de enntrada/salida en C++,

	cout << ... << endl; 
	cerr << ... << endl;

en Java es

	System.out.println(...); // System.out es la salida estándar
	System.err.println(...); // System.err es la salida de error estándar
 
Por ejemplo, en C++,

	cout << "¡Bienvenido, visitante número" << num_visitante << "!" << endl;

se traduce a Java por

	System.out.println("¡Bienvenido, visitante número" + num_visitante + "!");

El operador '+' actúa aquí como concatenador de cadenas.  'num_visitante',
que presumiblemente es un número, es convertido primero a cadena y luego
concatenado, de forma transparente al programador.

