/dev/misc

Séptimo arte

Ayer me salió mi espíritu explorador y decidí tomar una ruta desconocida hasta ese momento para ir al cine de arte que está a un lado del Tec de Mty. Tomé la ruta 95 en Aramberri, a un par de cuadras del departamento, y llegué sin contratiempos.

Había varias opciones, pero eran las 7pm y sólo había una película que empezaba a esa hora u otra a las 7:40. Leí las sinópsis y algo capturó mi atención en la película de las 7:40: la historia de la hija de un matemático. Yo tenía inclinaciones por ver la de Good Night, and Good Luck, pero la proyectaban hasta las nueve. Compré la entrada a la película de las 7:40.

¡Qué grandiosa película! Me encantó, me fascinó, la disfruté enormemente. No puedo evitar recomendarla, ¡véanla! es una orden. En inglés se llama Proof. Quisiera contarla, pero sería una injusticia.

Al salir quería otra vez tomar la ruta para regresar, pero no pasaba. Al comenzar un chipi chipi decidí abordar el primer taxi que viera. Al subirme la tromba hizo su aparición. Y no dejó de llover hasta ya muy entrada la noche. ¡Vaya que llueve por acá!

C++

He estado jugando mucho con C++.

Regla del diseño de software: ''PROGRAMA ORIENTADO A INTERFACES''. El objetivo de esto es mantener bajo el nivel de acoplamiento entre los objetos y facilitar el manejo de cambios en la implementación. Para los que ignoren la ventaja de esto, basta decir que los costos de mantenimiento del código decrecen sustancialmente.

El punto es que C++ es un lenguaje más bien de bajo nivel (comparado con Java o C#) y no provee un mecanismo nativo y claro para el manejo de interfaces, pero se puede hacer algo a través de la herencia de clases virtuales puras.

Después de pelarme con el compilador de mingw, con un trozo de código grande y algo complejo, decidí hacer una pequeña prueba de concepto para ver si cómo hacer esto y he aquí el resultado:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>

using namespace std;

// Interface
class IBar
{
public:
  virtual ~IBar () {};

  virtual void print () = 0;
};

// Implementation
class Bar : public IBar
{
public:
  Bar () { cout << "Constructor" << endl; }
  virtual ~Bar () { cout << "Destructor" << endl; }

  virtual void print () { cout << "Metodo print ()" << endl; }
};

// Class factory
class Factory
{
public:
  static IBar *createBar () {
    return new Bar ();
  }
};

// Program
int main (int argc, char **argv)
{
  IBar *bar = Factory::createBar ();
  bar->print ();
  delete bar;
}

Después me comencé a pelear con las excepciones y descubrí que si defines el tipo de retorno de la excepción, y al momento de atrapar la excepción lo haces con otra clase a la definida, el la aplicación truena pero gacho, a diferencia del g++ en Gentoo que fue muy generoso y expresivo. He aquí la prueba de concepto para ver como funcionan las excepciones:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>

using namespace std;

class IException
{
public:
  virtual ~IException () {}

  virtual void print () = 0;
};

class MyEx : public IException
{
public:
  MyEx () { cout << "Constructor" << endl; }
  virtual ~MyEx () { cout << "Destructor" << endl; }
  virtual void print () { cout << "Hubo un error" << endl; }
};

void failproc () // throw (MyEx *)
{
  throw (new MyEx ());
}

int main (int argc, char **argv)
{
  try {
    failproc ();
  } catch (IException *ex) {
    ex->print ();
    delete ex;
  }
}

¡Bellísimo! Así podemos tener excepciones específicas pero las capturamos todas bajo una interfaz.

El punto es hacer trabajar al compilador/máquina virtual para que resuelva los tipos de dato en tiempo de ejecución. De esta manera nuestra capa superior del software manejara las interfaces sin preocuparle que implementación está utilizando.

La frase del día en el chat: ''Lo único constante es lo que está de la chingada''.