Menu
Coddy logo textTech

Ponteiros Inteligentes em C++

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 15 de 104.

Ponteiros inteligentes são classes wrapper que gerenciam automaticamente a memória do heap para você. Eles eliminam a necessidade de chamadas manuais a delete, liberando a memória quando o ponteiro sai do escopo.

Inclua o cabeçalho <memory> para usar ponteiros inteligentes.

unique_ptr - propriedade exclusiva. Apenas um ponteiro pode ser proprietário do recurso por vez.

#include <memory>

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // Use como um ponteiro comum

// Não pode copiar, mas pode transferir a posse
std::unique_ptr<Player> player2 = std::move(player);
// player agora é nullptr

shared_ptr - propriedade compartilhada. Vários ponteiros podem ser proprietários do mesmo recurso. A memória é liberada quando o último proprietário é destruído.

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // Ambos possuem o recurso

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

weak_ptr - observador não proprietário de um shared_ptr. Útil para quebrar referências circulares.

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

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

Use unique_ptr por padrão para propriedade única. Use shared_ptr quando múltiplos objetos precisarem compartilhar um recurso. Use weak_ptr para observar sem estender o tempo de vida.

Prefira make_unique e make_shared em vez do new bruto.

challenge icon

Desafio

Fácil

Vamos criar um sistema de compartilhamento de documentos que demonstra os diferentes modelos de propriedade dos ponteiros inteligentes. Você verá como unique_ptr impõe a propriedade exclusiva, como shared_ptr permite vários proprietários e como weak_ptr pode observar sem afetar o tempo de vida.

Você criará dois arquivos para organizar seu código:

  • Document.h: Defina uma classe Document que represente um documento compartilhável. Ela deve ter:
    • Um atributo privado title (string)
    • Um construtor que receba um título e imprima "Document created: <title>"
    • Um destrutor que imprima "Document deleted: <title>"
    • Um método getTitle() que retorne o título
  • main.cpp: Demonstre os três tipos de ponteiros inteligentes lendo um título de documento da entrada e, em seguida:
    • Crie um unique_ptr para um Document com o título informado
    • Imprima "Unique owner: <title>"
    • Transfira a propriedade para outro unique_ptr usando std::move
    • Imprima "Ownership transferred"
    • Crie um shared_ptr para um novo Document com o título "SharedDoc"
    • Crie um segundo shared_ptr apontando para o mesmo documento
    • Imprima "Shared owners: <count>" usando use_count()
    • Crie um weak_ptr a partir de um dos ponteiros compartilhados
    • Use lock() para acessar o documento por meio do ponteiro fraco e imprima "Weak access: <title>"

Lembre-se de incluir <memory> para usar ponteiros inteligentes. Use std::make_unique e std::make_shared para criar seus ponteiros inteligentes. As mensagens do destrutor ajudarão você a ver quando cada documento é limpo automaticamente no final do programa.

Inclua seu arquivo de cabeçalho em main.cpp usando #include "Document.h".

Experimente você mesmo

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

using namespace std;

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

    // TODO: Criar um unique_ptr para um Document com inputTitle
    // usando std::make_unique

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

    // TODO: Transferir a posse para outro unique_ptr usando std::move

    // TODO: Imprimir "Ownership transferred"

    // TODO: Criar um shared_ptr para um novo Document com o título "SharedDoc"
    // usando std::make_shared

    // TODO: Criar um segundo shared_ptr apontando para o mesmo documento

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

    // TODO: Criar um weak_ptr a partir de um dos shared pointers

    // TODO: Usar lock() para acessar o documento através do weak_ptr
    // e imprimir "Weak access: <title>"

    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C++ online