Conceitos Essenciais de Ponteiros Inteligentes
Introdução aos Ponteiros Inteligentes
Ponteiros inteligentes são objetos que atuam como ponteiros, mas fornecem funcionalidades adicionais de gerenciamento de memória. Eles são definidos no cabeçalho <memory> e lidam automaticamente com a alocação e desalocação de memória.
Tipos de Ponteiros Inteligentes
| Ponteiro Inteligente |
Propriedade |
Caso de Uso |
unique_ptr |
Exclusiva |
Propriedade única |
shared_ptr |
Compartilhada |
Vários proprietários |
weak_ptr |
Não-proprietário |
Quebrar referências circulares |
unique_ptr: Propriedade Exclusiva
#include <memory>
#include <iostream>
class Resource {
public:
Resource() { std::cout << "Resource criado\n"; }
~Resource() { std::cout << "Resource destruído\n"; }
};
void demonstrateUniquePtr() {
// Propriedade exclusiva
std::unique_ptr<Resource> ptr1(new Resource());
// Transferência de propriedade
std::unique_ptr<Resource> ptr2 = std::move(ptr1);
// ptr1 agora é nulo, ptr2 possui o recurso
}
Fluxo de Propriedade unique_ptr
graph TD
A[Criar unique_ptr] --> B{Transferência de Propriedade?}
B -->|Sim| C[Mover Propriedade]
B -->|Não| D[Deleção Automática]
C --> D
shared_ptr: Propriedade Compartilhada
#include <memory>
#include <iostream>
void demonstrateSharedPtr() {
// Vários proprietários possíveis
auto shared1 = std::make_shared<Resource>();
{
auto shared2 = shared1; // Contagem de referências aumenta
// Tanto shared1 quanto shared2 possuem o recurso
} // shared2 sai de escopo, contagem de referências diminui
} // shared1 sai de escopo, recurso deletado
Mecanismo de Contagem de Referências
graph LR
A[Criação Inicial] --> B[Contagem de Referências: 1]
B --> C[Novo Ponteiro Compartilhado]
C --> D[Contagem de Referências: 2]
D --> E[Ponteiro Destruído]
E --> F[Contagem de Referências: 1]
F --> G[Último Ponteiro Destruído]
G --> H[Recurso Deletado]
weak_ptr: Quebrando Referências Circulares
class Node {
public:
std::shared_ptr<Node> next;
std::weak_ptr<Node> prev; // Evita vazamento de memória
};
void demonstrateWeakPtr() {
auto node1 = std::make_shared<Node>();
auto node2 = std::make_shared<Node>();
node1->next = node2;
node2->prev = node1;
// weak_ptr previne vazamento de memória por referência circular
}
Boas Práticas
- Prefira
unique_ptr para propriedade exclusiva
- Use
shared_ptr quando vários proprietários forem necessários
- Use
weak_ptr para quebrar potenciais referências circulares
- Evite gerenciamento de ponteiros brutos
Recomendação LabEx
Na LabEx, enfatizamos técnicas modernas de gerenciamento de memória C++. Ponteiros inteligentes fornecem uma maneira segura e eficiente de lidar com a alocação dinâmica de memória.
Principais Pontos
- Ponteiros inteligentes automatizam o gerenciamento de memória
- Diferentes ponteiros inteligentes resolvem cenários de propriedade diferentes
- Reduz erros relacionados à memória
- Melhora a segurança e a legibilidade do código