Puntero inteligente

Puntero inteligente

En programación, un puntero inteligente (o smart pointer) es un tipo abstracto de datos que simula el comportamiento de un Puntero (informática) pero añadiendo nuevas características adicionales, como recolector de basura automático y comprobador de límites. Estas características adicionales tienen como objetivo reducir errores causados por el mal uso de punteros, manteniendo la eficiencia. Los punteros inteligentes suelen llevar un registro de los objetos a los que apunta con el próposito de gestionar la memoria.

El mal uso de los punteros suele ser la mayor fuente de errores: asignaciones constantes, liberación de memoria y la referencia, que debe ser realizada por un programa usando punteros, introduce el riesgo de pérdidas de memoria. Los punteros inteligentes intentan prevenir las pérdidas de memoria, liberando automáticamente los recursos: cuando un puntero (o el último de una serie de punteros) a un objeto es destruido, porque por ejemplo se sale del ámbito, el objeto apuntado también se elimina.

Existen varios tipos de punteros inteligentes. Algunos trabajan llevando la cuenta de referencias, otros mediante asignación de un objeto a un único puntero. Si el lenguaje soporta recolector de basura automático (por ejemplo, Java), el uso de los punteros inteligentes es innecesario.

En C++, los punteros inteligentes pueden ser implementados como una "template class" que imita, mediante sobrecarga de operadores, el comportamiento de los punteros tradicionales, pero proporcionando algoritmos de administación de memoria.

Los punteros inteligentes pueden facilitar la programación internacional expresando el uso de un puntero en su propio tipo. Por ejemplo, si una función de C++ devuelve un puntero, no hay forma de saber cuando se debe liberar la memoria, cuando se ha terminado con el uso de la información.

algun_tipo* function_ambigua(); // ¿Qué se debería hacer con el resultado?

Tradicionalmente, esto se habría resuelto con comentarios, pero esto puede ser propenso a errores. Devolviendo un auto_pr de C++:

auto_ptr<algun_tipo> funcion_obvia1();

La función hace explicitamente que el "llamador" tenga la propiedad del resultado y, además, si no se hace nada, no se filtrará memoria. Del mismo modo, si la intención es devolver un puntero a un objeto gestionado en otros lugares, la función podría devolver una referencia:

algun_tipo& funcion_obvia2();


Contenido

Punteros inteligentes en Boost

La biblioteca Boost de C++ nos ofrece varios tipos de punteros inteligentes, los más importantes son:

  • Scoped Pointer: Puntero no copiable
  • Shared Pointer: Puntero copiable

Scoped pointer

Un scoped pointer es una clase de puntero inteligente que no puede copiarse, por lo que solo puede existir un punto de acceso al objeto que apunta. Cuando el puntero sale del ámbito, el objeto se destruye y la memoria se libera.

Sintaxis:

boost::scoped_ptr<MiClase> MiPuntero (new MiClase(1));
MiPuntero.reset(new MiClase(2));

Se puede acceder al contenido usando el operador *, acceder a la dirección con & y acceder al puntero en bruto con el metodo get().

Ejemplo:

#include <iostream>
using namespace std;
 
#include <boost/scoped_ptr.hpp>
 
/*
  Vamos a crear una clase que informe de cuándo se crea y cuando se
  destruye, y lleve un contador de elementos creados.
 
*/
 
class Elemento
{
  static int counter;
  int n;
public:
  Elemento():n(++counter){
    cout << "* Creando Elemento " << n << endl;
  };
 
  void lanzar(const char * msg){
    cout << "* Elemento " << n << " says: " << msg << endl;
  };
 
  virtual ~Elemento(){
    cout << "* So Long, Elemento " << n << endl;
  };
};
 
int Elemento::counter = 0;
 
int main(int argc, char *argv[])
{
 
  /*
    Utilizamos corchetes para abrir un nuevo entorno (scope) Vemos
    que al terminar el scope, el scoped pointer se libera
    automáticamente, mientras que en el caso del puntero clásico, si
    no liberamos manulmente se produciría una fuga de memoria.
  */
 
  cout << "Inicio del scope" << endl;
  {
    boost::scoped_ptr<Elemento> miElemento(new Elemento());
    miElemento -> lanzar("Mensaje desde myFun_1");
 
    Elemento * classicPointer = new Elemento();
    classicPointer -> lanzar ("Mensaje del elemento con puntero clásico");
 
    delete classicPointer; // Necesario borrarlo manualmente!
  }
  cout << "Fin del scope" << endl;
 
  /*
    Si tenemos un scoped pointer como atributo de una clase, o como
    variable suelta, es posible asignarle un valor utilizando el
    método reset, que borrará lo que estuviera contenido en el
    puntero previamente.
  */
 
  boost::scoped_ptr<string> ptrCadena;
  ptrCadena.reset(new string("Hola"));
 
  /*
    Los operadores habituales se conservan. En el caso del *, se
    devuelve una referencia &. Para acceder al puntero en bruto se
    utiliza el método get(), aunque NO SE RECOMIENDA, ya que hacer
    modificaciones o borrar el objeto apuntado a través de get()
    puede producir errores.
  */
 
  cout << "Longitud de cadena: " << ptrCadena -> length() << endl;
  cout << *ptrCadena << endl;
 
  return 0;
}

Shared pointer

Un shared pointer es un tipo de puntero inteligente que guarda un contador de referencias al objeto al que apunta. Cada vez que se hace una copia del puntero, se aumenta el contador. Cuando se destruye uno de los shared pointer, el contador disminuye.

Cuando el contador llega a cero, quiere decir que no hay más punteros apuntando al objeto, por lo que este puede destruirse y liberar la memoria que ocupa. Todo esto se hace de forma transparente al usuario.

Sintaxis:

boost::shared_ptr<MiClase> MiPuntero (new MiClase(1));
boost::shared_ptr<MiClase> OtroPuntero = MiPuntero;
MiPuntero.reset(new MiClase(2));

Ejemplo:

#include <iostream>
#include <string>
 
using namespace std;
 
int tabulados;
 
#include <boost/shared_ptr.hpp>
 
/*
  Tenemos dos clases. La clase Mirador tiene un shared pointer a
  Observado. 
*/
 
string tab(){
  return string(tabulados, '\t');
}
 
struct Observado{
  Observado(){ cout << tab() << "+ Creando Observado" << endl; }
  ~Observado(){ cout << tab() << "- Borrando Observado" << endl; }
};
 
struct Mirador{
  boost::shared_ptr<Observado> fan;
 
  Mirador(){ cout << tab() << "+ Creando Mirador" << endl; }
  ~Mirador(){ cout << tab() << "- Borrando Mirador" << endl; }
};
 
/*
  La función popular rellena el atributo del Mirador con un shared
  pointer a Observado.
 
*/
 
void popular(Mirador & m1, Mirador & m2){
  boost::shared_ptr<Observado> O(new Observado);
  m1.fan = O;
  m2.fan = O;
}
 
int main(int argc, char *argv[])
{
  tabulados = 0;
  cout << "-- Inicio" << endl;
  {
    tabulados ++;
    cout << tab() << "-- Inicio del primer scope" << endl;
    Mirador M1;
    {
      tabulados ++;
      cout << tab() << "-- Inicio del segundo scope" << endl;
      Mirador M2;
      popular(M1, M2);
      cout << tab() << "-- Fin del segundo scope" << endl;
    }
    tabulados --;
    cout << tab() << "-- Final del primer scope" << endl;
  }
  tabulados--;
  cout << "-- Fin" << endl;
 
  return 0;
}

Enlaces externos


Wikimedia foundation. 2010.

Игры ⚽ Нужно сделать НИР?

Mira otros diccionarios:

  • Club Ferro Carril Oeste — Este artículo o sección necesita referencias que aparezcan en una publicación acreditada, como revistas especializadas, monografías, prensa diaria o páginas de Internet fidedignas. Puedes añadirlas así o avisar …   Wikipedia Español

  • Callback (informática) — Saltar a navegación, búsqueda Un callback esta a menudo al mismo nivel del llamado original …   Wikipedia Español

  • LZSS — Este artículo o sección necesita una revisión de ortografía y gramática. Puedes colaborar editándolo (lee aquí sugerencias para mejorar tu ortografía). Cuando se haya corregido, borra este aviso por favor. El algoritmo de compresión lz77… …   Wikipedia Español

  • Forth — Saltar a navegación, búsqueda Para otros usos de este término, véase Forth (desambiguación). Forth o FORTH es un lenguaje de programación para computadores y un ambiente de programación ideado por Charles H. Moore y Elisabeth Rather entre los… …   Wikipedia Español

  • Club Atlético Boca Juniors — Existen desacuerdos sobre la neutralidad en el punto de vista de la versión actual de este artículo o sección. En la página de discusión puedes consultar el debate al respecto. Para otros clubes homónimos, véase Boca Juniors (desambiguación) …   Wikipedia Español

  • Notación húngara — En programación informática, la notación húngara es un sistema usado normalmente para crear los nombres de variables. También se utiliza para nombrar las instancias de objetos en lenguajes de programación visuales, como por ejemplo Delphi. El… …   Wikipedia Español

  • La era de las máquinas espirituales — (The Age of Spiritual Machines) es un libro de Ray Kurzweil (1998), de gran contenido filosófico, tecnológico, informático y científico que habla de la historia de la evolución y su relación con la vida natural y la tecnología, así como el papel… …   Wikipedia Español

  • Ernesto Mastrángelo — Saltar a navegación, búsqueda Ernesto Mastrángelo Nombre Ernesto Enrique Mastrángelo …   Wikipedia Español

  • Federico Faggin — Saltar a navegación, búsqueda Federico Faggin nació en Vicenza, Italia, el 1 de diciembre de 1941. Contenido 1 Educación y primeras experiencias profesionales en Italia 2 Carrera Profesional en Estados Unidos 3 …   Wikipedia Español

  • GNOME Do — en acción (Interfaz clásico) Desarrollador GNOME Do Core Team …   Wikipedia Español

Compartir el artículo y extractos

Link directo
Do a right-click on the link above
and select “Copy Link”