C++: Punteros inteligentes

Cómo crear un puntero único con C++ Smart Pointers

¡Prueba gratis durante 10 días

nuestros 1246 cursos !

Prueba gratis Mostrar modalidades de suscripción
Un puntero único es un puntero inteligente que no se puede copiar. Eso nos permite saber en todo momento que solo hay una copia de ese puntero y quién es su propietario. Vamos a ver cómo crearlos y qué podemos hacer con estos punteros.
06:47

Transcripción

Un puntero único es un tipo de puntero inteligente que no se puede copiar. Solo existe una única copia, por lo que no se pueden hacer copias suyas sin que te des cuenta. Y no hay ninguna duda de quién es su propietario. Aquí tengo una copia de "unique_ptr.cpp" de los archivos base. También tengo la clase "strc" abierta en este proyecto. La clase "strc" es una clase sencilla de "string" con instrucciones "print" para los constuctores y destructores. Aquí puedes ver los "msg". Si me voy aquí arriba, tenemos un "msg" para el constructor por defecto, un "msg" para el constructor "cstring", etc. para todos los constructores, el destructor y el operador de copia e intercambio. El objetivo es mostrar cómo gestionan un objeto los punteros inteligentes. Crea un puntero único. Aquí creamos un puntero único tal y como se haría con cualquier otro objeto plantilla. Aquí tenemos la firma de clase de plantilla, el puntero estándar único. El tipo es "strc". Después el número del objeto que se va a crear. Y entre paréntesis una expresión para crear el objeto. El operador "new" devuelve un puntero, y eso es lo que queremos para construir un puntero inteligente. Cuando compilo y ejecuto esto, me voy hacia arriba para que puedas ver el comienzo. Creo el puntero único "uno". Luego lo saco por pantalla con esta función "display", que tiene este aspecto. Puedes ver que pone "uno". También puedes ver que se llama al constructor "nstrc". El operador "new" crea un nuevo objeto y toma su dirección como un puntero. Eso se hace justo aquí, en el constructor "cstring", porque estoy pasando un "cstring" al constructor "strc". Esta es la forma habitual de crear un puntero único. Desde "C++14" hay una función plantilla "make_unique", pero este compilador no la admite. Por otro lado, es una función muy fácil de crear, así que la he incluido aquí. La puedes ver aquí: "namespace notstd". Como ves, la estoy usando con "notstd make_unique" y el tipo, y lo que hay en el constructor entre paréntesis ahí. Esta pequeña función plantilla imita lo que hace "make_unique" en "C++14". La he incluido aquí para que puedas ver cómo se hace. Esa debería ser la forma correcta de crear un puntero único y los compiladores están empezando a admitirla. De hecho, a fecha de hoy, el compilador "Microsoft Visual C++" que viene en el "Visual Studio 2013" admite "make_unique". Por eso la he puesto en el espacio de nombres "notstd". Si tienes un compilador que admite "make_unique", quita el "not" y "std make_unique" funcionará. Aquí no funciona porque no hay ningún "make_unique" en el espacio de nombres estándar. Aquí tenemos algunas cosas que puedes hacer con un puntero único. El método "reset" se utiliza para destruir un objeto. También para sustituirlo por uno nuevo. Cuando se llama a "reset", se llama al destructor de objeto que está justo aquí. Y luego se llama al constructor "new" y el nuevo objeto sustituye al antiguo. Aquí muestro "a" y "b" y obtengo "3" y "2". "b" es "2" y se está sustituyendo ahora por un "3". También puedo mover un puntero. Este movimiento, como "b" y "c" son realmente punteros, bueno, "b" es un puntero, y el "move" devuelve un puntero y crea automáticamente otro puntero del mismo tipo. Así que se mueve y no es necesario llamar a ningún constructor o destructor. Esta es una forma rápida y eficaz de mover punteros. Como este es un puntero único, obviamente no se puede copiar, por lo que si intento asignarlo sin copiarlo, verás que en realidad está aquí. Si intento compilar, me da el mensaje de error: "Llamada al constructor de copia borrado implícitamente", porque no hay ningún constructor de copia para este puntero único. Por eso el "move" funciona como podemos ver aquí. Para destruir un objeto debes llamar al metodo "reset" y el puntero inteligente se encarga de llamar al destructor. Puedes ver que ahora tanto "a" como "b" se han destruido, porque aquí arriba he quitado "a" "b". También puedo llamar a "reset c" así. De hecho el puntero único también tiene un método "release" que no te da la opción de sustituir el objeto con uno nuevo y tiene el mismo efecto, salvo que verás que no llama al destructor. La mayoría de las veces preferirás usar el "reset" en lugar de "release". Algo importante que puede que no sea obvio es que no puedes pasar un puntero único a una función, al menos no de la forma normal. Así que me voy a venir aquí y crear una función sencilla. La llamo "f". Usará un puntero único estándar de "strc" que vamos a llamar "p". Vamos a sacar un mensaje que diga que hemos llamado a "f". Vamos a mostrar "p" por pantalla. Voy a intentar pasarle "a" justo aquí. Pongo "f(a);", así. Cuando el compilador llega a esa instrucción nos da el mismo mensaje: "Llamada al constructor de copia borrado implícitamente". La razón es que estamos pasando el puntero por valor. Ese objeto de puntero inteligente no se puede copiar, porque es un puntero único. Así que si quiero pasar un puntero único a una función tengo que usar su referencia. Aquí estoy usando realmente la referencia del objeto puntero. Cuando compilo y ejecuto, y me voy hasta arriba, verás que ahora funciona. Estamos llamando a "f", que tiene el valor de "uno" porque se lo estamos pasando a "a". Por tanto, no puedes pasar un puntero por valor a una función, pero puedes pasar una referencia a cualquier puntero así, porque la referencia, lógicamente, no intenta hacer una copia del puntero. Los punteros únicos son una herramienta muy útil para gestionar la memoria y reducir las pérdidas de memoria. Algunas veces, sin embargo, necesitas tener varias copias de punteros. Para esos casos tenemos los punteros compartidos, que veremos en el próximo vídeo.

C++: Punteros inteligentes

Conoce los punteros inteligentes, un componente fundamental en C++, que garantizan que tanto la memoria como otros recursos se asignen de forma adecuada y eficaz.

25 min (7 Videos)
Actualmente no hay comentarios.
 
Software:
Fecha de publicación:14/12/2016

Este curso video2brain está disponible como descarga y para ser visualizado online. ¡Pero no hace falta que decidas entre las dos opciones! Al comprar el curso, disfrutarás de ambas posibilidades.

La descarga te permite ver las lecciones sin estar conectado/a a internet y supone una navegación fácil y ágil entre capítulo y capítulo. Si vas a trabajar en diferentes ordenadores o si no quieres descargarte el curso completo, entra en la web con tus datos de acceso y disfruta directamente de tus vídeos online. Te deseamos que disfrutes de este curso y te resulte de mucha utilidad.

Estamos a tu disposición si tienes cualquier tipo de duda o pregunta.