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;
    }
Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top