Como excluir intencionalmente um boost :: shared_ptr?
-
05-07-2019 - |
Pergunta
Eu tenho muitos objetos boost::shared_ptr<MyClass>
, e em algum momento eu intencionalmente quer delete
alguns deles para liberar alguma memória. (Eu sei que nesse ponto que eu nunca vai precisar da apontado para MyClass
objetos mais.) Como posso fazer isso?
Eu acho que você não pode simplesmente chamar delete()
com o ponteiro bruto que eu recebo com get()
.
Eu vi um get_deleter(shared_ptr<T> const & p)
função em boost::shared_ptr
, mas eu não tenho certeza de como usá-lo, e também diz experimental bem próximo a ela. (Eu acho que tenho impulso 1,38).
Talvez apenas atribuir um novo boost::shared_ptr
vazio para a variável? Que deve jogar fora o valor antigo e excluí-lo.
Solução
Você só faz
ptr.reset();
Veja a shared_ptr manual do . É equivalente a
shared_ptr<T>().swap(ptr)
Você chamada reset
em cada ponteiro inteligente que não deve fazer referência ao objeto mais. A última tais reset
(ou qualquer outra ação que faz com que a queda de contagem de referência para zero, na verdade) fará com que o objeto a ser free'ed usando o deleter automaticamente.
Talvez você esteja interessado no ponteiro inteligente . Ele tem uma entrada sobre atraso deallocation .
Outras dicas
Se você quer ser capaz de objetos intencionalmente delete (eu faço o tempo todo), então você tem que usar propriedade única. Você foi atraído para usar shared_ptr quando não é apropriado para o seu design.
O ponto inteiro de boost::shared_ptr<T>
é que o objeto pointee será eliminado exatamente no momento em que há shared_ptr<T>
s apontar para ele - isto é, quando o último shared_ptr<T>
apontando para esse objeto sai do escopo ou é transferido para apontar para um objecto diferente. Então, tudo que você tem que fazer para excluir um objeto é se certificar que não há shared_ptr<T>
s apontando para ele. Por exemplo. se você tiver apenas um único shared_ptr<T>
chamado p
apontando para um objeto, ou deixá-lo cair fora do escopo, ou p.reset()
chamada (equivalente a p = NULL
para um ponteiro normal), ou atribuí-lo ao ponto em outra coisa.
Se você tem duas shared_ptr<T>
s apontando para o objeto, você precisa transferir os dois.
EDIT: Graças a dehmann por apontar que p = NULL;
na verdade não é um código válido para uma shared_ptr<T>
...:)
O que você quer fazer é retorno referências fracas usando boost :: weak_ptr que pode ser convertido para um shared_ptr quando necessário. Isso pode permitir que você controle a vida útil do objeto na shared_ptr e aqueles que querem acesso pode segurar a weak_ptr e tentar converter para um shared_ptr. Se essa conversão falhar, então eles podem re-consulta e trazer o objeto de volta na memória.