Sobes.tech
Middle

De que componentes é composto um shared_ptr?

sobes.tech IA

Resposta da IA

shared_ptr consiste em dois componentes principais:

  1. Ponteiro para o recurso gerido: Ponteiro cru para o objeto que o shared_ptr gere.

  2. 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_ptr ou weak_ptr que 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_ptr que 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_ptr que 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) ]