Sobes.tech
Middle

Como funciona o unique_ptr em C++?

sobes.tech IA

Resposta da IA

std::unique_ptr — é um ponteiro inteligente que implementa a propriedade exclusiva de um objeto alocado dinamicamente. Ele garante a gestão automática de memória: o objeto apontado por unique_ptr é automaticamente eliminado na destruição de unique_ptr.

Características principais:

  • Propriedade exclusiva: Em qualquer momento, apenas um unique_ptr pode possuir um objeto em particular.
  • Ausência de cópia: unique_ptr não pode ser copiado. Isso impede a propriedade múltipla do mesmo objeto e o problema de "dupla eliminação".
  • Semântica de movimento: A propriedade do objeto pode ser transferida de um unique_ptr para outro usando a semântica de movimento (std::move).
  • Deleter configurável: Pode-se fornecer um deleter próprio para gerenciar formas específicas de liberar recursos.

O princípio de funcionamento baseia-se em RAII (Resource Acquisition Is Initialization): o recurso (memória alocada dinamicamente) é adquirido na criação do objeto (unique_ptr) e liberado na sua destruição.

#include <memory> // Para unique_ptr
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass criado\n"; }
    ~MyClass() { std::cout << "MyClass destruído\n"; }
};

int main() {
    {   
        // Criação de um unique_ptr que possui um objeto MyClass
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // Neste momento, ptr1 é o proprietário exclusivo do objeto
        // auto ptr2 = ptr1; // Erro de compilação: cópia proibida

        // Transferência de propriedade de ptr1 para ptr2
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // Após a movimentação, ptr1 não possui mais o objeto (tornou-se nullptr)
        if (!ptr1) {
            std::cout << "ptr1 não possui objeto: " << (ptr1 ? "Sim" : "Não") << "\n";
        }

        // O escopo de ptr2 termina aqui.
        // ptr2 é destruído, e o objeto MyClass que possui, é automaticamente eliminado.
    } // O objeto MyClass é destruído aqui

    std::cout << "Fim do main.\n";

    return 0;
}

Comparação com raw pointer:

Característica raw pointer std::unique_ptr
Propriedade do recurso Não definido Exclusiva
Eliminação automática Não Sim
Semântica de cópia Sim Não (apenas movimento)
Risco de vazamento de memória Alto Baixo

De modo geral, unique_ptr é a forma preferencial de gerenciar memória dinâmica em C++11 e versões superiores, especialmente quando se requer propriedade estrita e liberação automática de recursos.