Middle
De que componentes é composto um shared_ptr?
sobes.tech IA
Resposta da IA
shared_ptr consiste em dois componentes principais:
-
Ponteiro para o recurso gerido: Ponteiro cru para o objeto que o
shared_ptrgere. -
Ponteiro para o bloco de controlo (Control Block): Objeto que contém metainformação sobre o recurso gerido. Este bloco é alocado dinamicamente ao criar o primeiro
shared_ptrouweak_ptrque aponta para o recurso.
O bloco de controlo normalmente contém:
- Contador de referências fortes (Strong Reference Count): Número de instâncias de
shared_ptrque apontam para o recurso. Quando este contador chega a zero, o recurso é eliminado. - Contador de referências fracas (Weak Reference Count): Número de instâncias de
weak_ptrque apontam para o recurso. O recurso só é eliminado quando o contador de referências fortes chega a zero, independentemente do valor deste contador. No entanto, o bloco de controlo só é eliminado quando ambos os contadores atingem zero. - Informação sobre o deleter (Deleter): Função ou functor opcional para eliminar o recurso. Se não for especificado, usa-se
delete. - Informação sobre o alocador (Allocator): Alocador opcional para alocar recursos e o bloco de controlo.
Exemplo de criação de shared_ptr e seus componentes a nível conceptual:
// Suponha que exista uma classe MyClass
class MyClass {
public:
MyClass() { std::cout << "MyClass criado\n"; }
~MyClass() { std::cout << "MyClass destruído\n"; }
};
// Criação de shared_ptr:
// Alocação de um objeto MyClass
// Alocação do bloco de controlo
// Configuração do ponteiro para MyClass no shared_ptr
// Configuração do ponteiro para o bloco de controlo no shared_ptr
// Inicialização dos contadores (fortes = 1, fracos = 0) no bloco de controlo
std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();
// Ao criar uma cópia de shared_ptr:
// ptr2 aponta para o mesmo objeto MyClass
// ptr2 aponta para o mesmo bloco de controlo
// Aumenta o contador de referências fortes no bloco de controlo (agora 2)
std::shared_ptr<MyClass> ptr2 = ptr1;
// Ao destruir um shared_ptr (por exemplo, ptr1 sai do escopo):
// Diminui o contador de referências fortes no bloco de controlo (agora 1)
// O recurso NÃO é eliminado, pois o contador forte > 0
// Ao destruir o último shared_ptr (ptr2 sai do escopo):
// Diminui o contador de referências fortes no bloco de controlo (agora 0)
// O objeto MyClass é eliminado
// Diminui o contador de referências fracas no bloco de controlo (aqui 0)
// Ambos os contadores = 0, o bloco de controlo é eliminado
Representação visual:
shared_ptr|-> [ Seus dados (Ponteiro para o recurso, Ponteiro para o bloco de controlo) ]- [ Ponteiro para o recurso ] -> [ Objeto do tipo T ]
- [ Ponteiro para o bloco de controlo ] -> [ Objeto do bloco de controlo (Contadores, Deleter, Allocator) ]