# 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 gestión automática de memoria y comprobador de límites (bound checking). 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. Los punteros inteligentes se popularizaron por primera vez en el lenguaje de programación C++ durante la primera mitad de la década de 1990 como refutación a las críticas sobre la falta de recolección automática de basura en C++.
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. Los punteros inteligentes también eliminan los punteros colgantes al posponer la destrucción hasta que el recurso ya no esté en uso.
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 o C#), el uso de los punteros inteligentes es innecesario para los aspectos de recuperación y seguridad de la administración de memoria, pero son útiles para otros fines, como la administración de residencia de la estructura de datos de caché y la gestión de recursos de objetos como descriptores de archivos o sockets de red.

## Características

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.
Tradicionalmente, las convenciones de nomenclatura se han utilizado para resolver la ambigüedad, pero esto es un enfoque propenso a errores y laborioso, pero esto puede ser propenso a errores. Devolviendo un auto_ptr de C++:
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. En C++11, auto_ptr ha quedado obsoleto en favor de unique_ptr.
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:
En Object Pascal (Free Pascal o Delphi), también se pueden usar los punteros inteligentes mediante TSmartPointer.

## 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:
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:

### 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:
Ejemplo: