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?

Foi útil?

Solução

  1. Você pode destruir os objetos via instância de assinatura e ele removerá automaticamente os ponteiros.
  2. 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.
  3. Você pode atribuir um ID exclusivo a todos os objetos e depois remover através do ID exclusivo, não o shared_ptr
  4. 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!

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