Mantendo um std::set<boost::shared_ptr>
-
21-09-2019 - |
Pergunta
Estou escrevendo um jogo e um mecanismo que o acompanha em C++.O mecanismo depende muito da automação usando uma linguagem de script incorporada simples.Os scripts podem criar classes de objetos, definir ouvintes de eventos neles e produzir instâncias a partir deles.Atualmente, uma instância deve estar vinculada a um identificador global de script para preservar sua existência.O resultado óbvio disso é que não pode haver objetos anônimos, que serão de longe os mais comuns.
Atualmente, as instâncias são gerenciadas usando um std::set<Instance*, spatial_sort>
, onde spatial_sort
é um functor que classifica instâncias por posição, para renderização e detecção de colisão.As instâncias são removidas e reinseridas em cada quadro usando sua posição atual como uma dica, sob a suposição de que provavelmente não se moverão muito em um quinquagésimo de segundo.Se um dead
flag é definido na instância, ele é apagado do conjunto.O Instance
construtores e destruidores invocam insert(this)
e erase(this)
, respectivamente.
Para permitir instâncias anônimas, quero alterar o conjunto para um std::set<boost::shared_ptr<Instance>, spatial_sort>
, o que permitiria Instance
compartilhar a propriedade de instâncias e preservar sua existência até que elas se destruam.Infelizmente, porque as chamadas para insert()
precisa ser colocado no construtor, shared_from_this()
não funcionará para obter um shared_ptr
para o Instance
.Não importa nada disso Instance
acontece de já herdar de boost::enable_shared_from_this<>
através de sua classe base.
Alguém pode recomendar uma solução alternativa adequada?
Editar:
Eu fiz o que deveria ter feito em primeiro lugar e dividi o comportamento do Instance
classe em duas classes: Instance
e Reference
.A expressão new SomeClass
em um script, então retorna um Reference
para um novo Instance
.O Instance
os próprios objetos nunca são gerenciados usando um shared_ptr
, então eles são responsáveis por cometer suicídio em resposta a um evento adequado, por exemplo, fim da animação, fim do nível, etc.
Obrigado pela ajuda!A refatoração é uma solução tão boa quanto qualquer outra, se simplesmente funcionar.
Solução
Você poderia adicionar um método estático ao Instance
que você usa para criar novos objetos e que também faz o trabalho administrativo, como adicioná-lo ao conjunto:
static Instance* create(int something) {
boost::shared_ptr<Instance> sptr(new Instance(something));
instanceset.insert(sptr);
return sptr.get();
}
Se você quiser fazer desta a única maneira de construir um objeto desta classe, você também pode tornar o construtor normal privado ou protegido.
Para obter mais informações, consulte também a entrada C++ FAQ Lite sobre "Ligação dinâmica durante a inicialização", que não está diretamente relacionado, mas usa a mesma técnica para contornar as restrições ao uso de funções virtuais em construtores.