boost :: shared_ptr use_count
-
23-08-2019 - |
Pergunta
Eu estou tentando entender o que está acontecendo no código a seguir. Quando objeto-a é excluído, não é variável membro shared_ptr objeto-B permanece na memória porque objeto-c detém uma shared_ptr para objeto-b?
class B
{
public:
B(int val)
{
_val = val;
}
int _val;
};
class A
{
public:
A()
{
_b = new B(121);
}
boost::shared_ptr<B> _b;
};
class C
{
public:
C()
{
}
void setRef( boost::shared_ptr<B> b)
{
_b = b;
}
boost::shared_ptr<B> _b;
};
int main()
{
C c;
{
A *a = new A();
cout << "a._b.use_count: " << a->_b.use_count() << endl;
c.setRef(a->_b);
cout << "a._b.use_count: " << a->_b.use_count() << endl;
delete a;
}
cout << c._b->_val << endl;
}
Solução
O A
-objeto vai ser limpo assim que a
é excluído no final do seu bloco. Mas o shared_ptr ele contém foi posteriormente copiado, incrementando sua contagem de referência.
Assim, o B
-objeto terá uma contagem de referência de 2 após c.setRef
(referenciado pela A
-objecto e por C
do shared_ptr
-objeto). Quando a
é excluído no final do seu bloco, em seguida, a contagem de referência do B
-objeto cai para 1
novamente desde shared_ptr única de c
está referenciando-lo agora.
Após c
é destruído no final do principal, a sua shared_ptr
será destruído também como parte da destruição do c
, e agora como a contagem de referência cai para zero, o objecto pontiagudo-a B
serão excluídos por shared_ptr
.
Assim, as contagens de referência do B
-objeto:
0: before existence of a.
1: from start of lifetime of a until c.setRef
2: from c.setRef until copy of its parameter
3: from copy of c.setRef''s parameter until return of it
2: from return of c.setRef until end of a''s block
1: from end of a''s block until end of main
0: after main returned (object doesn''t exist anymore now)
Outras dicas
Não, quando um for excluído, a -.> _ B (o ponteiro em si) deixará de existir
O objeto que a -.> _ B aponta para continuarão a existir, porque c._b ainda pontos a ele
O alvo da shared_ptr
permanecerá vivo até que a referência final para que ele seja excluído. Neste caso, isso será quando a instância C
sai do escopo.