fbpx
Wikipedia

Puntero inteligente

En programación, un puntero inteligente (o smart pointer) es un tipo abstracto de datos que simula el comportamiento de un puntero corriente 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 propósito 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 administración de memoria.

Los punteros inteligentes pueden facilitar la programación intencional 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_ptr de C++:

auto_ptr<algun_tipo> funcion_obvia1(); 

La función hace explícitamente 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(); 


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 método 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

  • Capítulo de muestra "Smart Pointers" del libro Modern C++ Design: Generic Programming and Design Patterns Applied por Andrei Alexandrescu, Addison-Wesley, 2001.
  • Código de ejemplo "countptr.hpp" del libro The C++ Standard Library - A Tutorial and Reference por Nicolai M. Josuttis
  • Artículo "" [1]
  • Artículo "" por Herb Sutter
  • "Smart Pointers - What, Why, Which?" por Yonat Sharon
  • "Smart Pointers Overview" por John M. Dlugosz
  • YASPER library otra implementación de punteros inteligentes en C++
  • Smart Pointers en Delphi
  •   Datos: Q1665677

puntero, inteligente, programación, puntero, inteligente, smart, pointer, tipo, abstracto, datos, simula, comportamiento, puntero, corriente, pero, añadiendo, nuevas, características, adicionales, como, recolector, basura, automático, comprobador, límites, est. En programacion un puntero inteligente o smart pointer es un tipo abstracto de datos que simula el comportamiento de un puntero corriente pero anadiendo nuevas caracteristicas adicionales como recolector de basura automatico y comprobador de limites Estas caracteristicas 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 proposito de gestionar la memoria El mal uso de los punteros suele ser la mayor fuente de errores asignaciones constantes liberacion de memoria y la referencia que debe ser realizada por un programa usando punteros introduce el riesgo de perdidas de memoria Los punteros inteligentes intentan prevenir las perdidas de memoria liberando automaticamente los recursos cuando un puntero o el ultimo de una serie de punteros a un objeto es destruido porque por ejemplo se sale del ambito el objeto apuntado tambien se elimina Existen varios tipos de punteros inteligentes Algunos trabajan llevando la cuenta de referencias otros mediante asignacion de un objeto a un unico puntero Si el lenguaje soporta recolector de basura automatico 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 administracion de memoria Los punteros inteligentes pueden facilitar la programacion intencional expresando el uso de un puntero en su propio tipo Por ejemplo si una funcion 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 informacion algun tipo function ambigua Que se deberia hacer con el resultado Tradicionalmente esto se habria resuelto con comentarios pero esto puede ser propenso a errores Devolviendo un auto ptr de C auto ptr lt algun tipo gt funcion obvia1 La funcion hace explicitamente que el llamador tenga la propiedad del resultado y ademas si no se hace nada no se filtrara memoria Del mismo modo si la intencion es devolver un puntero a un objeto gestionado en otros lugares la funcion podria devolver una referencia algun tipo amp funcion obvia2 Indice 1 Punteros inteligentes en Boost 1 1 Scoped pointer 1 2 Shared pointer 2 Enlaces externosPunteros inteligentes en Boost EditarLa biblioteca Boost de C nos ofrece varios tipos de punteros inteligentes los mas importantes son Scoped Pointer Puntero no copiable Shared Pointer Puntero copiableScoped pointer Editar 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 ambito el objeto se destruye y la memoria se libera Sintaxis boost scoped ptr lt MiClase gt MiPuntero new MiClase 1 MiPuntero reset new MiClase 2 Se puede acceder al contenido usando el operador acceder a la direccion con amp y acceder al puntero en bruto con el metodo get Ejemplo include lt iostream gt using namespace std include lt boost scoped ptr hpp gt Vamos a crear una clase que informe de cuando 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 lt lt Creando Elemento lt lt n lt lt endl void lanzar const char msg cout lt lt Elemento lt lt n lt lt says lt lt msg lt lt endl virtual Elemento cout lt lt So Long Elemento lt lt n lt lt 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 automaticamente mientras que en el caso del puntero clasico si no liberamos manulmente se produciria una fuga de memoria cout lt lt Inicio del scope lt lt endl boost scoped ptr lt Elemento gt miElemento new Elemento miElemento gt lanzar Mensaje desde myFun 1 Elemento classicPointer new Elemento classicPointer gt lanzar Mensaje del elemento con puntero clasico delete classicPointer Necesario borrarlo manualmente cout lt lt Fin del scope lt lt endl Si tenemos un scoped pointer como atributo de una clase o como variable suelta es posible asignarle un valor utilizando el metodo reset que borrara lo que estuviera contenido en el puntero previamente boost scoped ptr lt string gt ptrCadena ptrCadena reset new string Hola Los operadores habituales se conservan En el caso del se devuelve una referencia amp Para acceder al puntero en bruto se utiliza el metodo get aunque NO SE RECOMIENDA ya que hacer modificaciones o borrar el objeto apuntado a traves de get puede producir errores cout lt lt Longitud de cadena lt lt ptrCadena gt length lt lt endl cout lt lt ptrCadena lt lt endl return 0 Shared pointer Editar 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 mas 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 lt MiClase gt MiPuntero new MiClase 1 boost shared ptr lt MiClase gt OtroPuntero MiPuntero MiPuntero reset new MiClase 2 Ejemplo include lt iostream gt include lt string gt using namespace std int tabulados include lt boost shared ptr hpp gt Tenemos dos clases La clase Mirador tiene un shared pointer a Observado string tab return string tabulados t struct Observado Observado cout lt lt tab lt lt Creando Observado lt lt endl Observado cout lt lt tab lt lt Borrando Observado lt lt endl struct Mirador boost shared ptr lt Observado gt fan Mirador cout lt lt tab lt lt Creando Mirador lt lt endl Mirador cout lt lt tab lt lt Borrando Mirador lt lt endl La funcion popular rellena el atributo del Mirador con un shared pointer a Observado void popular Mirador amp m1 Mirador amp m2 boost shared ptr lt Observado gt O new Observado m1 fan O m2 fan O int main int argc char argv tabulados 0 cout lt lt Inicio lt lt endl tabulados cout lt lt tab lt lt Inicio del primer scope lt lt endl Mirador M1 tabulados cout lt lt tab lt lt Inicio del segundo scope lt lt endl Mirador M2 popular M1 M2 cout lt lt tab lt lt Fin del segundo scope lt lt endl tabulados cout lt lt tab lt lt Final del primer scope lt lt endl tabulados cout lt lt Fin lt lt endl return 0 Enlaces externos EditarCapitulo de muestra Smart Pointers del libro Modern C Design Generic Programming and Design Patterns Applied por Andrei Alexandrescu Addison Wesley 2001 Codigo de ejemplo countptr hpp del libro The C Standard Library A Tutorial and Reference por Nicolai M Josuttis Articulo Smart Pointers in Boost 1 Articulo The New C Smart er Pointers por Herb Sutter Smart Pointers What Why Which por Yonat Sharon Smart Pointers Overview por John M Dlugosz YASPER library otra implementacion de punteros inteligentes en C Smart Pointers en Delphi Datos Q1665677Obtenido de https es wikipedia org w index php title Puntero inteligente amp oldid 125248997, wikipedia, wiki, leyendo, leer, libro, biblioteca,

español

, española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos