Sobes.tech
Junior

Que ponteiros inteligentes (smart pointers) conhece?

sobes.tech IA

Resposta da IA

std::unique_ptr, std::shared_ptr, std::weak_ptr, std::auto_ptr (obsoleto em C++11 e removido em C++17).

  • std::unique_ptr: Propriedade exclusiva do recurso. O recurso é libertado quando o ponteiro sai do âmbito ou é redefinido. Não permite cópia, apenas movimento.

    #include <memory>
    
    int main() {
        std::unique_ptr<int> ptr(new int(5));
        // std::unique_ptr<int> ptr2 = ptr; // Erro: não pode copiar
        std::unique_ptr<int> ptr3 = std::move(ptr); // Movimento
        return 0;
    }
    
  • std::shared_ptr: Propriedade partilhada do recurso. Usa um contador de referências. O recurso é libertado quando o último shared_ptr que aponta para ele sai do âmbito ou é redefinido. Suporta cópia.

    #include <memory>
    
    int main() {
        std::shared_ptr<int> ptr1(new int(10));
        std::shared_ptr<int> ptr2 = ptr1; // Cópia, aumenta o contador de referências
        return 0;
    }
    
  • std::weak_ptr: Não possui o recurso e não aumenta o contador de referências de shared_ptr. É usado para evitar referências cíclicas entre shared_ptr. Para aceder ao recurso, obtém-se um shared_ptr através do método lock().

    #include <memory>
    
    int main() {
        std::shared_ptr<int> shared_ptr_inst(new int(20));
        std::weak_ptr<int> weak_ptr_inst = shared_ptr_inst; // Criação de weak_ptr
    
        if (auto locked_ptr = weak_ptr_inst.lock()) {
            // `shared_ptr` obtido com sucesso, pode usar o recurso
        } else {
            // O recurso já foi libertado
        }
        return 0;
    }
    
  • std::auto_ptr: Ponteiro inteligente obsoleto com semântica de propriedade na cópia, o que levava a comportamentos não evidentes. Não deve ser usado em código novo.

Diferenças entre shared_ptr e weak_ptr:

Característica std::shared_ptr std::weak_ptr
Propriedade do recurso Sim Não
Contador de referências Aumenta Não aumenta
Libertação do recurso Sim, quando o contador = 0 Não
Referências cíclicas Pode causar problemas Ajuda a prevenir
Acesso ao recurso Diretamente com operator*, operator-> Através do método lock()