Archivo por meses: agosto 2007

En Ourense

Pues me dió el venazo y el lunes me vine a Ourense a casa de unos amigos. Casi estaba como un gallego, que no sabía si venía o no :P. A ver cómo se porta la semana. De momento ha estado bien, aunque haya amanecido lloviendo hoy. He visto las Burgas, unos manantiales de agua caliente (muy caliente) que sale directamente del suelo (vale, ahora está puesto para que parezca una fuente, pero es completamente natural) y ayer nos fuimos a comer a un pueblo pulpo y carne al preparadas de forma típica :) (ñam! que rico).

A ver si hago fotos y las cuelgo; aunque vamos, tal y como está el día, creo que pocas fotos haré :(

¿Qué superhéroe eres?

Desde el blog de Jorge he visto este otro test y este ha sido el resultado (yo me avergüenzo de él :P):

Tus resultados:
Tu Eres Supergirl (Superchica)

Supergirl (Superchica)
70%
Robin
67%
Hulk
65%
Wonder Woman (Mujer Maravilla)
60%
Iron Man (El Hombre de Hierro)
60%
Batman
60%
Superman (Superhombre)
60%
Spider-Man (El Hombre Araña)
55%
Catwoman (Gatúbela)
55%
Green Lantern (Linterna Verde)
55%
El Flash
55%
Cortada, muscular y femenina.
Honesta y defensora de los inocentes.


Chascar aquí para tomar la prueba de la personalidad del super héroe

De boda

Este finde he estado en Ciudad Real para asistir a la boda de un familiar. Debo decir que pese a mi edad, es a la primera boda que asisto :S

Creo, personalmente, que la ceremonia religiosa sobra un poco. Al menos yo preferiría no haber asistido a ésta. En general estaba muy bien montada y organizada. Los puntos en contra a destacar de este caso son:

  • El DJ: era malo, pero maaaaalo.
  • El volumen de la música: si estas comiendo en una boda, la música debe ser para acompañar, no para impedir que hables con el de al lado.
  • La música: como el DJ era malo, no era capaz de poner temas adecuados en los momentos oportunos
  • Las mesas: demasiado grandes, no permitian que hablases con el de enfrente.
  • La comida: personalmente, era demasiada (pero vamos, se perdona un poco :P).

Habría que hacer una lista de los elementos de una boda perfecta, de momento yo pongo algunos:

  • La comida: yo optaría por poca cosa en cada plato, pero sí mucha variedad y si se puede, calidad.
  • Lugar: a ser posible en un sitio abierto. El campo siempre será más bonito que un salon enorme.
  • Momento del día: a media tarde (el atardecer es bonito, y verlo desde el campo, comiendo, más).

¿Y vosotros que añadirías/cambiaríais?

Far, far away

Con las fiestas de Leganés ya en su apogeo, sushu y yo hemos decidio emigrar lejos de ahí para poder descansar traquilos. Para ello nos hemos buscado a alguien que nos soporte y crea que somos buenas personas (ingenua persona… :P).

Así que desde aquí, lejos de ruido infernal provocado por peñas sin respeto alguno a las normas de convivencia, hemos pasado una semana de lo más tranquila :) ¡Y hasta hemos tenido partida de rol! :D

Esta noche volveré para Leganés y mañana rumbo a Ciudad Real.

Punteros inteligentes en C++ (smart pointers) 3

En el artículo anterior nos quedamos con que hacía falta añadir nuevas funcionalidades que nos permitan mejorar las características del invento. Así que vamos a empezar poco a poco.

Para empezar, vamos a suponer que queremos poder asignar un puntero con el operador =. Para ellos hacemos lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<typename _t> class PtrSimple2 {
[..]
   PtrSimple2<_t>&
   // </_t>
   operator=( const PtrSimple2<_t>& ptr ) {
      // Hay que decrementar el puntero viejo, y en caso necesario
      // liberar la memoria
      (*_count) = (*_count) - 1;
      if( *_count == 0 ) {
         delete _count;
         delete _ptr;
      }
      _count = ptr._count;
      _ptr = ptr._ptr;
      (*_count) = (*_count) + 1;
 
      return *this;
   }
[..]
};
//</_t></typename>

Con esto ya tendríamos la asignación, pero sigue existiendo un problema de base: ¿qué pasa con la herencia? Por ejemplo, tenemos una clase A y otra B que hereda de A. Si yo creo que puntero de tipo A y otro de tipo B, me gustaría poder pasar sin problemas de uno a otro y que lo reconozca (¿sería lo lógico, no?). Pues tal y como están las cosas ahora, no lo haría (haced la prueba si no me creéis). Para solventar esto, añadimos los siguientes fragmentos de código:

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
template<typename _t> class PtrSimple2 {
//</typename>
[..]
public:
   // Para poder leer el puntero sin problemas
   _t* get_ptr() {
      return _ptr;
   }
 
   // Nuevo constructor
   // Estoy simplificando algunas cosas, es posible que no se pueda acceder
   // directamente a los miembros del otro puntero
   template<typename _u> PtrSimple2( const PtrSimple2<_u>& ptr ) {
      _count = ptr._count;
      _ptr = dynamic_cast<_t *>( ptr._ptr );
      (*count) = (*count) + 1;
   } // </_t></_u></typename>
 
   // Con el operador = hay que hacer lo mismo
   template<typename _u> PtrSimple2<_t>& operator=( const PtrSimple2<_u>& ptr ) {
      // Hay que decrementar el puntero viejo, y en caso necesario
      // liberar la memoria
      (*_count) = (*_count) - 1;
      if( *_count == 0 ) {
         delete _count;
         delete _ptr;
      }
      _count = ptr._count;
      _ptr = dynamic_cast<_t *>( ptr._ptr );
      (*_count) = (*_count) + 1;
 
      return *this;
   }
[..]
};
//</_t></_u></_t></typename>

¿Con esto ya estaría todo resuelto, no? Podemos controlar la herencia, los punteros, etc. Eso sí, siempre y para todo hay que utilizar este tipo de dato. Entonces, ¿puede haber casos en los que esto no funcione? La respuesta es sí. Imaginemos que tenemos que pasar a un método el la dirección a la que apuntamos (lo que hacemos con get_ptr) y luego podemos, desde otro lado, tomar dicha dirección en otro puntero.

Esta situación tan incomoda se pude solucionar con una política aún más agresiva de control de punteros. Para esto, debemos separar la parte de los contadores de punteros de la del propio control de los punteros. Vamos a ver otra clase para hacer punteros inteligentes que sigue una política un poco más agresiva:

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// ESTO VA EN LA CABECERA
 
void pointer_inc_ref( void *ptr );
bool pointer_dec_ref( void *ptr );
 
/**
 * Creates a smart pointer type that can free the memory used
 * automatically when it isn't necesary.
 * This pointer type can be very slow.
 */
template<typename _t> class pointer_to {
	Type *ptr;
 
public:
	pointer_to( _t *pointer ) {
		ptr = pointer;
		pointer_inc_ref(ptr);
	}
 
	pointer_to( const pointer_to<_t>& pointer ) {
		ptr = pointer.ptr;
		pointer_inc_ref(ptr);
	}
 
	template<typename _u> pointer_to( const pointer_to<_u>& pointer ) {
		ptr = dynamic_cast<_t *>( pointer.get() );
		pointer_inc_ref( ptr );
	}
 
	~pointer_to() {
		if( pointer_dec_ref( ptr ) )
			delete ptr;
	}
 
	_t* get() const {
		return ptr;
	}
 
	_t* operator->() const {
		return ptr;
	}
 
	_t& operator*() const {
		return *ptr;
	}
 
	// </_t>
	pointer_to<_t>& // </_t>
	operator=( const pointer_to<_t>& pointer ) {
		// </_t>
		if( pointer_dec_ref(ptr) )
			delete ptr;
		ptr = pointer.ptr;
		pointer_inc_ref(ptr);
	}
 
	pointer_to<_t>& operator=( _t*pointer ) {
		if( pointer_dec_ref(ptr) )
			delete ptr;
		ptr = pointer;
		pointer_inc_ref(ptr);
		return *this;
	}
 
	template<typename _u> pointer_to<_t>& operator=( const pointer_to<_u>& pointer ) {
		if( pointer_dec_ref(ptr) )
			delete ptr;
		ptr = dynamic_cast<_t>( pointer.ptr );
		pointer_inc_ref(ptr);
		return *this;
	}
}; // class pointer_to
// </_t></_u></_t></typename></_t></_u></typename></_t></typename>
 
 
// ESTO VA EN EL CODIGO
 
typedef map<void *, int> pointer_map_t;
typedef pointer_map_t::iterator pointer_map_iterator;
//</void>
static map<void *, int> pointer_map;
 
void pointer_inc_ref( void *ptr )
{
	if( ptr != 0 ) {
		pointer_map_iterator it;
		it = pointer_map.find( ptr );
		if( it == pointer_map.end() ) {
			pointer_map.insert(pointer_map_t::value_type(ptr, 1));
		}
		else {
			pointer_map[ptr] ++;
		}
	}
}
 
bool pointer_dec_ref( void *ptr )
{
	if( ptr != 0 ) {
		pointer_map[ptr] --;
		if( pointer_map[ptr] == 0 ) {
			pointer_map.erase(ptr);
			return true;
		}
	}
	return false;
}
//</void>

En este caso, estamos haciendo una política muy agresiva, pero ya se controlan casi todos los casos (aún pueden existir problemas, para los que la política a utilizar sería que el puntero inteligente no libere la memoria [por lo que sería una perdida utilizarlo]). Además, existen problemas de dobles enlaces que podrían provocar que la memoria nunca se libere.

Seguro que hay mejores modos de hacerlo, pero este es, el que a partir de algunas cosillas que he leído por ahí he conseguido implementar. Si hay alguna pregunta (y habéis sido capaces de leer hasta aquí) no os cortéis en hacerla.

Planet Terror

Acabo de ver Planet Terror en el cine, mi opinión: la mejor película que he visto tras Braindead :P

La verdad es que han sabido dar la estética exacta para alegrarme la tarde (no voy a entrar en detalles, que son muchos y es mejor verlos). Sin duda, es una peli hecha para verla en la pantalla grande. Eso sí, no esperéis un gran guión ni nada por el estilo, solo explisiones, sangre y violencia subrealista.

El Quijote

Después de casi un año y dos meses de lectura (muyyyy pausada, eso sí) he conseguido terminarme las dos partes del Quijote de Cervantes. Entremedias ha habido más un libro y comic, pero hace tiempo que hice parón para dedicarle tiempo sólo al Quijote (cosa que, por cierto, no hacía).

Tras la lectura, diría que el primer libro es un compendio de política moderna, donde una persona se olvida de lo realmente importante (su hacienda, su familia, etc.) y se dedica a inventar estupideces (gigantes, ejercitos…) y trata de convencer a los demás de que son reales. Aparte de esto, esta primera parte del Quijote tiene gran cantidad de historias paralelas, ajenas a Quijote y Sancho.

La segunda parte del Quijote cambia un poco, ahora hay menos historias paralelas desligadas a los protagonistas y hay Don Quijote parece algo más cuerdo. Parece más centrado en las bromas que le gastan a ellos que a las invenciones de los mismos (que también las hay).

La lectura me ha resultado pesada, poco acostumbrado a leer que estoy y el lenguaje utilizado, me llevan a hacer un gran esfuerzo por leerlo (el caso es que las novelas ejemplares me costaron menos…).

¿Cúal será el siguiente en caer? La lista no es pequeña…