Utilisation de boost :: shared_ptr dans la hiérarchie d'héritage
-
05-07-2019 - |
Question
Imaginez la situation suivante:
class IAlarm : public boost::enable_shared_from_this<IAlarm> {
boost::shared_ptr<IAlarm> getThisPointerForIAlarm() {
return shared_from_this();
}
void verifyThis(int); // called by Device
};
class Alarm : public IAlarm {
Alarm( boost::shared_ptr< Device > attachedDevice){
attachedDevice->attachAlarm(this->getThisPointerForIAlarm());
}
void sendAlarm(){
attachedDevice->Alarm();
}
};
class Device {
attachAlarm( boost::shared_ptr< IAlarm > ia){
this->alarm=ia;
}
};
Je souhaite associer une alarme à un périphérique. Les alarmes et les appareils ne sont pas autorisés à se connaître (cela entraînerait une dépendance circulaire). C'est pourquoi j'utilise la classe d'interface IAlarm. Enfin, je souhaite pouvoir connecter plusieurs alarmes à un périphérique. Les alarmes peuvent accéder au périphérique auquel elles sont connectées et les périphériques peuvent lancer la vérification sur les alarmes connectées
Tout est sympa. Mais si j'essaie de relier une alarme à un périphérique, j'obtiens les informations suivantes:
boost::shared_ptr<Device> ptrDevice(new Device());
boost::shared_ptr<IAlarm> ptrAlarm(new Alarm( ptrDevice ));
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
what(): tr1::bad_weak_ptr
Quel est exactement le problème? Cette configuration fonctionnait plus ou moins avant d’utiliser boost :: shared_ptr
avec des références et des pointeurs purs. Est-il possible d'obtenir ce travail avec boost: shared_ptr
?
La solution
L'appel à shared_from_this ()
n'est valide que s'il est appelé sur un objet alloué dynamiquement appartenant à un shared_ptr
(voir la configuration requise figurant dans la documentation ). Cela signifie qu'il doit exister un shared_ptr
propriétaire de l'objet, sinon shared_from_this ()
ne fonctionnera pas.
Cela signifie notamment que vous ne pouvez pas (réussir) appeler shared_from_this ()
dans le constructeur, car l'objet est en cours de construction et n'est pas encore la propriété de shared_ptr
instance.
Pour contourner ce problème, il est préférable de déplacer le code qui associe l'alarme du constructeur à une méthode distincte appelée après la construction complète de l'objet:
boost::shared_ptr<Alarm> a(new Alarm());
a->attach(attachedDevice);