Categories

El puntero this

Para cada objeto declarado de una clase se mantiene una copia de sus campos, pero todos comparten la misma copia de los métodos de la clase.

Cada método de una clase puede hacer referencia a los campos de un objeto, modificarlos o leerlos, pero si sólo hay una copia del método y varios objetos de esa clase, ¿cómo hace el método para referirse a un dato de un objeto en concreto?

La respuesta es: usando el puntero especial llamado this.
Se trata de un puntero que tiene asociado cada objeto y que apunta a si mismo. Ese puntero se usa para acceder a sus miembros.

El puntero this nos permite acceder a los campos del objeto que llama al método.

EJEMPLO EN C++:

En este ejemplo se ilustra una forma de saber si el objeto que se pasa como parámetro es el mismo que el que hace la llamada (comprueba si ambos apuntan al mismo sitio).

using namespace std;

class clase {
  public:
   clase() {}
   void EresTu(clase& c) {
      if(&c == this) cout << "Sí, soy yo." << endl;
      else cout << "No, no soy yo." << endl;
   }
};
   
int main() {
   clase c1, c2;
   
   c1.EresTu(c2);
   c1.EresTu(c1);
}
OTRO EJEMPLO EN C++: Tenemos la siguiente clase pareja.
class pareja {
   public:
      // Constructor
      pareja(int a2, int b2);
      // Funciones miembro de la clase "pareja"
      void Lee(int &a2, int &b2);
      void Guarda(int a2, int b2);
   private:
      // Datos miembro de la clase "pareja"
      int a, b; 
};
Con la clase Guarda, asignamos los enteros que le pasamos al método como parámetros a los campos del objeto que ha hecho la llamada. La forma más sencilla de hacer esto sería así:
void pareja::Guarda(int a2, int b2) {
   a = a2;
   b = b2;
}
Pero para ver el funcionamiento del this, tambien lo podriamos hacer así:
void pareja::Guarda(int a2, int b2) {
   this->a = a2;
   this->b = b2;
}
En .NET el uso es el mismo pero cambiando el this-> por this. EJEMPLO EN .NET:
public class Person
{
   string firstName;
   string lastName;
   DateTime birthDate;

   public Persona(string firstName, string lastName, DateTime birthDate)
   {
       this.firstName = firstName;
       this.lastName = lastName;
       this.birthDate = birthDate;
   }
}

Parametros de entrada por VALOR o por REFERENCIA

Seguimos con el recordatorio de C++ comparando la forma en que le pasamos los parametros a una función o procedimiento.

Hay dos formas:

Por VALOR

Los parámetros de entrada (valor) se usan para proporcionar información de entrada a un
procedimiento. Dentro de éste pueden considerarse como variables cuyo valor inicial es el resultado de
evaluar los parámetros actuales. Como parámetro actual debe aparecer una expresión cuyo resultado
sea un valor de un tipo asignable al correspondiente parámetro formal. Puesto que las variables usadas
como parámetros formales de entrada no sirven para cambiar a los parámetros actuales (sólo para
conocer su valor en el momento de la llamada y asignarle un nombre a ese valor dentro del
procedimiento) se les suele denominar Parámetros por valor.

Ejemplo:

void dibLineas( int anchura, int altura )
{
int nFila;
int nColumna;
for( nFila = 1 ; nFila <= altura; ++nFila )
{
for( nColumna = 1; nColumna <= anchura; ++nColumna )
{
cout << "-";
}
cout << endl;
}
}


Por REFERENCIA

Para usar parámetros de entrada/salida, el parámetro formal debe estar precedido por el símbolo & y el parámetro actual debe ser una variable (no una expresión cualquiera). Los parámetros de entrada/salida se usan cuando se desea que un procedimiento MODIFIQUE el contenido de la variable actual. El hecho de definir estos parámetros explícitamente como variables hace consciente al programador de los lugares donde un procedimiento cambia a una variable que se le pase como parámetro. El funcionamiento de los parámetros de entrada/salida está basado en pasar al procedimiento una referencia a la variable actual en lugar de su valor.

Ejemplo:
void raices( double a, double b, double c, double &R1, double &R2 )
{
   double DiscriminanteS;
   // Se supone un discriminante positivo
   DiscriminanteS = sqrt( b*b-4.0*a*c );
   R1 = (-b + DiscriminanteS) / (2.0*a);
   R2 = (-b - DiscriminanteS) / (2.0*a);
}

Funciones y Procedimientos

Hagamos un breve recordatorio de C++.

En C++ no hay diferencias entre procedimientos y funciones: todo son funciones, con la diferencia de que un procedimiento es una función que no devuelve nada (void).

Es decir:

Función: Devuelven resultado en el return.

Ejemplo:

int mi_funcion( int x)
{
return 0;
}


Procedimiento: No devuelven resultado.

Ejemplo:
void dibLineas( int anchura, int altura )
{
  int nFila;
  int nColumna;

  for( nFila = 1 ; nFila <= altura; ++nFila )
  {
    for( nColumna = 1; nColumna <= anchura; ++nColumna )
    {
      cout << "-";
    }
    cout << endl;
  }
}

Clasificación de los lenguajes

Aunque existan cientos de lenguajes diferentes, estos se pueden agrupar segun las distintas filosofías que han seguido y la forma de trabajar que implican.

Lenguajes procedimentales o imperativo


El paradigma por procedimientos, representa el enfoque tradicional del proceso de programación.
Se define el proceso de programación como el desarrollo de procedimientos que, al seguirse, manipulan los datos para producir el resultado deseado. Así, el paradigma por procedimientos nos dice que abordemos un problema tratando de hallar un método para resolverlo, es decir, se pregunta ¿Qué procedimiento necesitamos para resolver el problema?  (uso de funciones)

EJEMPLO: Ansi-C



Lenguajes declarativos


En contraste, consideremos el paradigma declarativo que hace hincapié en la pregunta ¿Cuál es el problema? en vez de ¿Qué procedimiento necesitamos para resolver el problema?. Lo importante aquí es descubrir e implantar un algoritmo general para la resolución de problemas, después de lo cual se podrán resolver éstos con sólo expresarlos en una forma compatible con dicho algoritmo y aplicarlo. En este contexto, la tarea del programador se reduce a crear un enunciado preciso del problema, más que a descubrir un algoritmo para resolverlo.

Desde luego, el principal obstáculo para crear un lenguaje de programación basado en el paradigma declarativo es el descubrimiento del algorimo básico para resolver problemas. Por esta razón, los lenguajes declarativos tienden a ser de propósito específico, diseñados para usarse en aplicaciones particulares.

EJEMPLO: SQL



Lenguajes funcionales


la programación funcional es un paradigma de programación declarativa basado en la utilización de funciones aritméticas que no maneja datos mutables o de estado.
Enfatiza la aplicación de funciones, en contraste con el estilo de programación imperativa, que enfatiza los cambios de estado.

En la práctica, la diferencia entre una función matemática y la noción de una "función" utilizada en la programación imperativa es que las funciones imperativas pueden tener efectos secundarios, al cambiar el valor de calculos realizados previamente. Por esta razón carecen de transparencia referencial, es decir, la misma expresión lingüística puede resultar en valores diferentes en diferentes momentos dependiendo del estado del programa siendo ejecutado. Con código funcional, en contraste, el valor generado por una función depende exclusivamente de los argumentos alimentados a la función. Al eliminar los efectos secundarios se puede entender y predecir el comportamiento de un programa mucho más fácilmente, y esta es una de las principales motivaciones para utilizar la programación funcional.

EJEMPLO: R, Mathematica.

Se usan sobre todo en programas matemáticos


Programación con lenguajes Orientados a Objetos


El término programación orientada a objetos se refiere a un estilo de programación por lo que un lenguaje orientado a objetos puede ser tanto imperativo como declarativo; lo que los caracteriza es la forma de manejar la información: clase, objeto y herencia. En este enfoque, las unidades de datos se consideran objetos activos, en vez de las unidades pasivas contempladas por el paradigma por procedimientos tradicional.

Para aclarar esto, consideremos una lista de nombres.

En el paradigma por procedimientos, esta lista no es más que una colección de datos, y cualquier programa que quiera trabajar con ella deberá incluir los algoritmos para realizar las manipulaciones requeridas. Así, la lista es pasiva en el sentido de que la mantiene un programa controlador, en vez de tener la responsabilidad de mantenerse ella misma.

En el enfoque orientado a objetos la lista se considera como un objeto formado por la lista misma y por una serie de rutinas para manipularla. Por ejemplo, pueden ser rutinas para insertar una nueva entrada en la lista, para detectar si la lista está vacía o para ordenar la lista. De este modo, un programa que obtiene acceso a esta lista no necesita contener algoritmos para efectuar esas tareas; simplemente aprovecha las rutinas suministradas en el objeto.

EJEMPLO: C++

Blog Archive

Download

Javier Prieto Diaz. Con la tecnología de Blogger.