💻 Exemplos: Capítulo 10: Ponteiros Inteligentes: unique_ptr, shared_ptr e weak_ptr

Especialização em Sistemas com C++ • Demonstrações Práticas Compiláveis


🎯 Objetivo dos Exemplos

Apresentar a gestão moderna de recursos e propriedade de memória com os ponteiros inteligentes da biblioteca padrão (<memory>): propriedade exclusiva com std::unique_ptr (zero overhead de runtime), propriedade compartilhada com contador de referência atômico via std::shared_ptr, e quebra de ciclos de referência cruzada com std::weak_ptr.


1. Código Fonte Completo (main.cpp)

/**
 * @file main.cpp
 * @brief Gerenciamento de memória com std::unique_ptr, std::shared_ptr e std::weak_ptr em C++20.
 */

#include <iostream>
#include <memory>
#include <string>

class ServicoKernel {
public:
    std::string nome;

    explicit ServicoKernel(std::string n) : nome(std::move(n)) {
        std::cout << "[Kernel] Servico '" << nome << "' criado no Heap." << '\n';
    }

    ~ServicoKernel() {
        std::cout << "[Kernel] Servico '" << nome << "' destruido da memoria." << '\n';
    }

    void processar() const {
        std::cout << "  -> Executando carga de trabalho no servico: " << nome << '\n';
    }
};

// Demonstração de ciclo quebrado com std::weak_ptr
struct NoGrafo;
struct NoGrafo {
    std::string id;
    std::shared_ptr<NoGrafo> proximo;
    std::weak_ptr<NoGrafo> vizinho_fraco; // weak_ptr NÃO incrementa use_count, prevenindo leak!

    explicit NoGrafo(std::string i) : id(std::move(i)) {
        std::cout << "[Grafo] Vertice '" << id << "' alocado." << '\n';
    }
    ~NoGrafo() {
        std::cout << "[Grafo] Vertice '" << id << "' desalocado." << '\n';
    }
};

int main() {
    std::cout << "=== CAPÍTULO 10: SMART POINTERS MODERNOS EM C++20 ===" << '\n';

    // 1. std::unique_ptr com std::make_unique (Propriedade Exclusiva)
    std::cout << "\n--- 1. std::unique_ptr e Transferência de Propriedade ---" << '\n';
    {
        auto servico = std::make_unique<ServicoKernel>("Daemon_Monitoramento");
        servico->processar();

        // Transferência de posse (Move)
        std::unique_ptr<ServicoKernel> outro_dono = std::move(servico);
        if (!servico) {
            std::cout << "Ponteiro original esvaziado com sucesso via std::move." << '\n';
        }
        outro_dono->processar();
    } // outro_dono sai de escopo -> objeto é destruído automaticamente aqui

    // 2. std::shared_ptr e Contador de Referências
    std::cout << "\n--- 2. std::shared_ptr e use_count ---" << '\n';
    {
        std::shared_ptr<ServicoKernel> ref1 = std::make_shared<ServicoKernel>("Gateway_Compartilhado");
        std::cout << "Contador de referencias (use_count): " << ref1.use_count() << '\n';

        {
            std::shared_ptr<ServicoKernel> ref2 = ref1; // Compartilha posse
            std::cout << "Novo observador adicionado. use_count: " << ref1.use_count() << '\n';
            ref2->processar();
        } // ref2 sai de escopo

        std::cout << "Apos destruicao do observador. use_count: " << ref1.use_count() << '\n';
    } // ref1 sai de escopo -> destruído aqui

    // 3. std::weak_ptr para Quebrar Ciclos
    std::cout << "\n--- 3. std::weak_ptr para Prevenção de Referências Circulares ---" << '\n';
    {
        auto noA = std::make_shared<NoGrafo>("Nodo_Alpha");
        auto noB = std::make_shared<NoGrafo>("Nodo_Beta");

        noA->proximo = noB;
        noB->vizinho_fraco = noA; // Ligação fraca segura

        if (auto lockA = noB->vizinho_fraco.lock()) {
            std::cout << "Acesso com sucesso ao vizinho fraco: " << lockA->id << '\n';
        }
    } // Ambos os nós saem de escopo e são 100% destruídos sem vazamento de memória

    return 0;
}

2. Instruções de Compilação e Execução

# Compilação com GCC / Clang
g++ -std=c++20 -Wall -Wextra -O2 main.cpp -o app_smart_ptr
./app_smart_ptr

# Compilação com MSVC
cl /std:c++20 /EHsc /W4 /O2 main.cpp /Fe:app_smart_ptr.exe
.\app_smart_ptr.exe

3. Saída Esperada no Terminal

=== CAPÍTULO 10: SMART POINTERS MODERNOS EM C++20 ===

--- 1. std::unique_ptr e Transferência de Propriedade ---
[Kernel] Servico 'Daemon_Monitoramento' criado no Heap.
  -> Executando carga de trabalho no servico: Daemon_Monitoramento
Ponteiro original esvaziado com sucesso via std::move.
  -> Executando carga de trabalho no servico: Daemon_Monitoramento
[Kernel] Servico 'Daemon_Monitoramento' destruido da memoria.

--- 2. std::shared_ptr e use_count ---
[Kernel] Servico 'Gateway_Compartilhado' criado no Heap.
Contador de referencias (use_count): 1
Novo observador adicionado. use_count: 2
  -> Executando carga de trabalho no servico: Gateway_Compartilhado
Apos destruicao do observador. use_count: 1
[Kernel] Servico 'Gateway_Compartilhado' destruido da memoria.

--- 3. std::weak_ptr para Prevenção de Referências Circulares ---
[Grafo] Vertice 'Nodo_Alpha' alocado.
[Grafo] Vertice 'Nodo_Beta' alocado.
Acesso com sucesso ao vizinho fraco: Nodo_Alpha
[Grafo] Vertice 'Nodo_Alpha' desalocado.
[Grafo] Vertice 'Nodo_Beta' desalocado.