Menu
Coddy logo textTech

Punteros inteligentes en C++

Parte de la sección Programación Orientada a Objetos del Journey de C++ de Coddy. Lección 15 de 104.

Los punteros inteligentes son clases envolventes que administran automáticamente la memoria del montón por ti. Eliminan la necesidad de realizar llamadas manuales a delete al liberar la memoria cuando el puntero sale de ámbito.

Incluya el encabezado <memory> para usar punteros inteligentes.

unique_ptr: propiedad exclusiva. Solo un puntero puede ser propietario del recurso a la vez.

#include <memory>

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Usar como un puntero regular

// No se puede copiar, pero se puede transferir la propiedad
std::unique_ptr<Player> player2 = std::move(player);
// player ahora es nullptr

shared_ptr: propiedad compartida. Varios punteros pueden ser propietarios del mismo recurso. La memoria se libera cuando se destruye el último propietario.

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Ambos son dueños del recurso

std::cout << p1.use_count();  // Imprime 2

weak_ptr: observador no propietario de un shared_ptr. Útil para romper referencias circulares.

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // Convertir a shared_ptr
    locked->attack();
}

Usa unique_ptr por defecto para propiedad única. Usa shared_ptr cuando varios objetos necesiten compartir un recurso. Usa weak_ptr para observar sin extender el tiempo de vida.

Prefiere make_unique y make_shared en lugar de new directamente.

challenge icon

Desafío

Fácil

Construyamos un sistema para compartir documentos que demuestre los diferentes modelos de propiedad de los punteros inteligentes. Verás cómo unique_ptr impone una propiedad exclusiva, cómo shared_ptr permite múltiples propietarios y cómo weak_ptr puede observar sin afectar al tiempo de vida.

Crearás dos archivos para organizar tu código:

  • Document.h: Define una clase Document que represente un documento que se puede compartir. Debe tener:
    • Un atributo privado title (cadena)
    • Un constructor que reciba un título e imprima "Document created: <title>"
    • Un destructor que imprima "Document deleted: <title>"
    • Un método getTitle() que devuelva el título
  • main.cpp: Demuestra los tres tipos de punteros inteligentes leyendo el título de un documento desde la entrada y, después:
    • Crea un unique_ptr a un Document con el título introducido
    • Imprime "Unique owner: <title>"
    • Transfiere la propiedad a otro unique_ptr usando std::move
    • Imprime "Ownership transferred"
    • Crea un shared_ptr a un nuevo Document con el título "SharedDoc"
    • Crea un segundo shared_ptr que apunte al mismo documento
    • Imprime "Shared owners: <count>" usando use_count()
    • Crea un weak_ptr a partir de uno de los punteros compartidos
    • Usa lock() para acceder al documento mediante el puntero débil e imprime "Weak access: <title>"

Recuerda incluir <memory> para los punteros inteligentes. Usa std::make_unique y std::make_shared para crear tus punteros inteligentes. Los mensajes del destructor te ayudarán a ver cuándo se limpia automáticamente cada documento al final del programa.

Incluye tu archivo de cabecera en main.cpp usando #include "Document.h".

Pruébalo tú mismo

#include <iostream>
#include <memory>
#include <string>
#include "Document.h"

using namespace std;

int main() {
    string inputTitle;
    cin >> inputTitle;

    // TODO: Crear un unique_ptr a un Document con inputTitle
    // usando std::make_unique

    // TODO: Imprimir "Unique owner: <title>"

    // TODO: Transferir la propiedad a otro unique_ptr usando std::move

    // TODO: Imprimir "Ownership transferred"

    // TODO: Crear un shared_ptr a un nuevo Document con el título "SharedDoc"
    // usando std::make_shared

    // TODO: Crear un segundo shared_ptr que apunte al mismo documento

    // TODO: Imprimir "Shared owners: <count>" usando use_count()

    // TODO: Crear un weak_ptr a partir de uno de los punteros compartidos

    // TODO: Usar lock() para acceder al documento a través de weak_ptr
    // y imprimir "Weak access: <title>"

    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de C++ online