Shared Pointers de C++0x

En C usted puede hacer esto:
#include <stdlib.h>

struct Persona { };

int main()
{
Persona* a = malloc(sizeof(Persona));
free(a);
return 0;
}

Un ejemplo equivalente en C++:
class Persona { };

int main()
{
Persona* a = new Persona();
delete a;
return 0;
}

Por cada malloc existe un free (al menos que use reallocs), y por cada new existe un delete (y por cada new[] un delete[]).

¿Existe una forma por la cual C++ se "entere" que ya no quiero usar un puntero? La respuesta es: No, no existe. C++ no tiene un garbage collector. Pero existen clases que pueden ayudarnos, como el viejo y tan poco querido auto_ptr, o los mejorados unique_ptr, shared_ptr y weak_ptr del nuevo estándar de C++0x (o el TR1).

Un shared pointer es una clase que se encarga de guardar un puntero a un objeto (o tipo de dato), y cuenta la cantidad de referencias que se están haciendo a dicho objeto (es decir, la cantidad de shared pointers que apuntan al mismo objeto). El último shared pointer que se destruya (cuando las referencias llegan a cero), será el encargado de borrar el objeto apuntado (mediante un simple delete).

Un ejemplo:
#include <iostream>
#include <memory> // Aquí debería estar shared_ptr<> (GCC 4.4)

using namespace std;

class Persona {
int n;

public:
Persona(int n) : n(n) {
cout << "Nace la persona " << n << "\n";
}

~Persona() {
cout << "Muere la persona " << n << "\n";
}

static shared_ptr<Persona> Crear(int n) {
return shared_ptr<Persona>(new Persona(n));
}
};

int main()
{
shared_ptr<Persona> a(new Persona(1));
shared_ptr<Persona> b = Persona::Crear(2);
shared_ptr<Persona> c;

cout << "--- Aquí ambas personas existen ---\n";

c = a; // Aquí c apunta a la persona 1
b = c; // Ahora b apuntará a la persona 1 (la persona 2 muere porque
// ya no existen referencias a ella)

cout << "--- Aquí la persona 2 ya no existe ---\n";

return 0;
} // Aquí muere la persona 1 (a, b, c apuntaban a ella)
La salida del anterior programa es esta:
Nace la persona 1
Nace la persona 2
--- Aquí ambas personas existen ---
Muere la persona 2
--- Aquí la persona 2 ya no existe ---
Muere la persona 1
Como puede ver, en el anterior programa se llama sólo dos veces a "new Persona" y dos veces al destructor ~Persona. No debemos preocuparnos por usar "delete", el shared_ptr<> hace todo por nosotros.

¿Cómo hago para que la clase shared_ptr funcione en VS2008 SP1 Express? Debe definir _HAS_TR1 antes de incluir el archivo <memory>. Ejemplo:
#ifdef _MSC_VER      // Si estamos usando el compilador de Microsoft
#define _HAS_TR1 1 // Esto hará que se incluyan las clases del TR1 (std::tr1)
#endif

#include <iostream>
#include <memory>

using namespace std;
#ifdef _MSC_VER
using namespace std::tr1; // para tener shared_ptr<> disponible
#endif

// Resto del ejemplo...