Devo trovare una soluzione per consentire a una sottoclasse di ottenere il proprio puntatore intelligente.Sottoclassi e get_shared_from_this()
class Parent : public enable_shared_from_this {
...
}
class Child : public Parent {
public Child(){
boost::shared_ptr<Parent> pointer=shared_from_this(); // should work
boost::shared_ptr<Child> pointer=shared_from_this(); // won't work.
...
}
Come faccio ad avere il puntatore intelligente destra utilizzando shared_from_this()?
CONTESTO:
sto scrivendo un po 'di roba notificante/ascoltatore, e alcune classi sarà naturalmente necessario registrarsi e si annullare la registrazione al notificatore. Ad esempio,
class Body : extends Listener<BodyMessage>{ // listen for BodyMessage messages
public:
Body() {
Notifier<BodyMessage>::register(this); // register with the appropriate notifier
}
virtual ~Body {
Notifier<BodyMessage>::unregister(this); // unregister
}
bool notify(BodyMessage m){ ... }
...
}
Normalmente mi sarebbe solo utilizzare il puntatore questo, e tutto sarebbe andato bene. Ho ottenuto che Notifier usasse i modelli, così posso passare i messaggi solo a quelli che vogliono ascoltarli.
Tuttavia, voglio utilizzare i puntatori intelligenti. Se il notificante è simile al seguente:
template<typename t>
class Notifier {
public:
static void register<boost::shared_ptr<Listener<t>>> boost::shared_ptr<Listener<t>> listener);
...
}
quindi non posso utilizzare il puntatore questo più. Naturalmente, ho fatto corpo estendere enable_shared_from_this:
class Body : public boost::enable_shared_from_this, public Listener<BodyMessage> {
public:
Notifier<BodyMessage>::register(get_shared_ptr());
...
}
E che sembra opere per Enti. Non funziona, tuttavia, per sottoclassi dei corpi (o, almeno, non sembra):
class BodyChild : public Body {
public:
BodyChild(){
Notifier<BodyMessage>::register(get_shared_ptr());
}
probabilmente perché non riesco a lanciare uno shared_pointer. Allora, posso ottenere una soluzione che
- mi permette di usare puntatori condivisi per gli ascoltatori (dal momento che questi ascoltatori sono utilizzati anche in altri contesti di puntatore intelligente),
- mi permette di template Notifier e gli ascoltatori, utilizzando il tipo di messaggio stesso per il modello, quindi è estremamente semplice ascoltare i messaggi specifici e quindi non devo decodificare un messaggio, e
- è semplice?
Sono aperto ad altre idee, ma se riesco a farlo funzionare, sarò elettrizzato.
divertenti, mi sono imbattuto contro questo molto problema oggi. L'utilizzo di puntatori intelligenti per il pattern Observer si è rivelato un'ottima idea. Puoi anche usare 'boost :: signals' per far eseguire la metà del lavoro automaticamente (specialmente con gli oggetti' scoped_connection'). –
Perché hai bisogno/vuoi 'std :: shared_ptr' per il tuo sistema notificatore/listener?Gli ascoltatori dovrebbero essere effettivamente di proprietà dei notificanti, in modo che vengano distrutti una volta che tutti i notificanti sono spariti? O ci sono in realtà altri oggetti, che possiedono gli oggetti in ascolto e possono occuparsi dell'istanziazione e della costruzione? Quando ho costruito un sistema del genere, ho trovato abbastanza utile mantenere un sacco di controllo e non darlo via. – LiKao
@LiKao: Un modo per scrivere il pattern di osservatore è infatti di far sì che gli ascoltatori mantengano in vita i notificanti e di annullare la distruzione (shared_ptr + boost :: signal è eccellente per scrivere questo in <50 LOC). Al contrario, ho scoperto che attenersi a qualcosa di molto semplice e rigido in questa situazione aiuta a scrivere un codice migliore (leggi: più mantenibile). –