在继承层次结构中使用boost::shared_ptr

4

想象以下情况:

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;
   }
};

我想把一个警报附加到设备上。 警报和设备不允许彼此了解(这将导致循环依赖)。 这就是为什么我使用接口类IAlarm的原因。 最后,我希望能够将多个警报附加到一个设备上。 警报可以访问其附加的设备,并且设备可以启动对所附加警报的验证。
所有东西都编译得很好。 但如果我尝试将警报附加到设备上,我会得到以下结果:
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

到底是什么问题?在使用引用和纯指针的情况下,这个设置之前更或多或少地工作过。是否可能使用boost::shared_ptr使其正常工作?


1
你没有展示实际的代码,因此很难对其进行任何评估。 - KayEss
@KayEss:我同意。这里缺少太多了。 - Fred Larson
"alarm"是如何声明的?为什么要使用this->alarm而不仅仅是"alarm"? - user3458
设备不应该从IAlarm派生。 实际的代码太长了,无法贴出。但是给定的代码片段或多或少反映了问题。 Alarm声明如下: boost::shared_ptr<IAlarm> ptrAlarm(new Alarm( ptrDevice )); this->alarm=xy和alarm=xy有区别吗? - Maus
1个回答

15

如果在拥有shared_ptr的动态分配对象上调用,那么调用shared_from_this()才是有效的(请参见文档中列出的要求)。这意味着必须存在一个拥有该对象的shared_ptr,否则shared_from_this()将不起作用。

特别地,这意味着您不能在构造函数中(成功地)调用shared_from_this(),因为对象只是正在构建中,并且尚未被任何shared_ptr实例所拥有。

为了解决这个问题,最好将附加警报的代码从构造函数移动到一个单独的方法中,在对象完全构造后调用该方法:

boost::shared_ptr<Alarm> a(new Alarm());
a->attach(attachedDevice);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接