shared_ptr, assinatura, destruidor
-
20-09-2019 - |
Pergunta
Estou usando ponteiros de boost/shared_ptr em todo o meu aplicativo. Quando a última referência a um objeto é liberada, Shared_Ptr excluirá o objeto para mim. Os objetos no aplicativo assinam eventos em um local central do aplicativo, semelhante ao padrão de observador/assinante.
Nos destruidores do objeto, o objeto não se cancela a partir da lista de assinaturas. A lista de assinaturas é essencialmente apenas um list<weak_ptr<MyObject> >
. O que eu quero fazer é algo semelhante a isso:
Type::~Type()
{
Subscriptions::Instance()->Remove(shared_from_this());
}
Meu problema aqui é que Shared_From_Hes não pode ser chamado em destruidores, para que o código acima lançará uma exceção.
Na minha antiga implementação, a lista de assinaturas era apenas uma lista de ponteiros e depois funcionou. Mas quero usar referências fracas_ptr para reduzir o risco de estragar a memória pelo gerenciamento manual da memória.
Como eu confio no Shared_ptr para fazer a exclusão de objetos, não há um lugar único no meu código, onde eu possa fazer logicamente uma chamada para cancelar a inscrição.
Alguma idéia do que fazer nessa situação?
Solução
- Você pode destruir os objetos via instância de assinatura e ele removerá automaticamente os ponteiros.
- Você pode esquecer de removê -los das assinaturas - os fracos de qualquer maneira não poderão ser trancados de qualquer maneira, então você pode removê -los.
- Você pode atribuir um ID exclusivo a todos os objetos e depois remover através do ID exclusivo, não o shared_ptr
- Você pode passar um ponteiro normal para remover em vez de um compartilhado - ele servirá como um "ID".
Outras dicas
Meu problema aqui é que
shared_from_this
Não pode ser chamado nos destruidores, para que o código acima faça uma exceção.
Vai jogar uma exceção Porque expirou, por definição, em um destruidor.
Então, o que você quer, afinal? Um ponteiro compartilhado "expirado"? Basta criar um ponteiro compartilhado vazio.
Ou um ponteiro fraco expirado?
Talvez se você perceber que o "problema" não é shared_from_this
jogar (é um sintoma), mas todos os proprietários sendo inerentemente já redefinido ou destruído Nesse ponto, e os indicadores fracos expirados e equivalentes a um padrão vazio criaram ponteiro fraco (*), então você deve passar por um ponteiro fraco inicializado padrão.
Também Subscriptions::Instance()->Remove(weak_OR_owning_pointer)
Não faz sentido de qualquer maneira (com o ponteiro fraco ou possuindo), pois você não pode comparar um ponteiro fraco com qualquer coisa, você só pode tentar travá -lo (e depois fazer uma comparação).
Então você pode simplesmente remover dicas fracas expiradas. Os argumentos de Remove
é inútil.
(*) Isso ou você tem um bug duplo muito sério de propriedade dupla do objeto que está sendo destruído!