Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 子类并从_this()获取_shared__C++_Inheritance_Boost_Subclass_Shared Ptr - Fatal编程技术网

C++ 子类并从_this()获取_shared_

C++ 子类并从_this()获取_shared_,c++,inheritance,boost,subclass,shared-ptr,C++,Inheritance,Boost,Subclass,Shared Ptr,我需要找到一个解决方案,允许子类获得正确的智能指针 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> point

我需要找到一个解决方案,允许子类获得正确的智能指针

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.

  ...
}
类父级:公共从\u启用\u共享\u{
...
}
类子:公共父类{
公共儿童(){
boost::shared_ptr pointer=shared_from_this();//应该可以工作
boost::shared_ptr pointer=shared_from_this();//不起作用。
...
}
如何使用_this()中的共享_获取正确的智能指针

背景:

我正在写一些通知程序/侦听器的东西,有些类自然需要从通知程序中注册和注销它们自己

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){ ... }

  ...
}
类主体:扩展侦听器{//侦听主体消息
公众:
正文(){
通知程序::注册(this);//向适当的通知程序注册
}
虚拟人体{
通知程序::取消注册(此);//取消注册
}
bool notify(bodymessagem){…}
...
}
通常我只会使用this指针,一切都会很好。我已经让通知程序使用模板,所以我只能将消息传递给想要听到它们的人

但是,我想使用智能指针。如果通知程序如下所示:

template<typename t>
class Notifier {
  public:
    static void register<boost::shared_ptr<Listener<t>>> boost::shared_ptr<Listener<t>> listener);

  ...
}
模板
类通知程序{
公众:
静态无效寄存器boost::shared_ptr listener);
...
}
那么我就不能再使用this指针了。当然,我让Body extend enable_shared_来自以下内容:

class Body : public boost::enable_shared_from_this, public Listener<BodyMessage> {
  public:
    Notifier<BodyMessage>::register(get_shared_ptr());
  ...
}
类主体:public boost::从公共侦听器启用共享{
公众:
通知程序::注册(获取共享的ptr());
...
}
这似乎对身体有效。然而,对身体的子类不起作用(或者,至少,它似乎不起作用):

class BodyChild:公共机构{
公众:
BodyChild(){
通知程序::注册(获取共享的ptr());
}
可能是因为我无法强制转换共享的_指针。那么,我可以制定一个解决方案吗

  • 让我为侦听器使用共享指针(因为这些侦听器也用于其他智能指针上下文)
  • 让我使用消息类型本身作为模板,对通知程序和侦听器进行模板化,这样就非常容易侦听特定消息,因此我不必解码消息
  • 简单吗
我对其他想法持开放态度,但如果我能让它起作用,我会很激动。

你可以投射智能指针,Boost为你提供了一些模板来简化这一点。你可以使用例如
静态指针投射
动态指针投射
来“穿透”指针

由于
this
是正确的动态类型,因此您可以调用
boost::static\u pointer\u cast
shared\u的返回值从\u this()

boost::shared_ptr p=static_pointer_cast(shared_from_this());

(由于Koenig查找,无需限定
static\u pointer\u cast

有趣的是,我今天遇到了这个问题。在观察者模式中使用智能指针是一个非常好的主意。您还可以使用
boost::signals
自动完成一半的工作(尤其是
作用域连接
对象).为什么您需要/想要通知程序/侦听器系统使用std::shared_ptr?侦听器是否应该归通知程序所有,以便在所有通知程序都离开后将其销毁?或者在构建此类系统时,是否确实存在其他对象,它们拥有侦听对象并可以负责实例化和构造,我发现实际上保留很多控制权而不放弃它是非常有帮助的。@LiKao:编写观察者模式的一种方法确实是让侦听器让通知器保持活动状态,并且在销毁时不受限制(shared_ptr+boost::signals非常适合在<50 LOC的地方编写).相反,我发现在这种情况下坚持一些非常简单和僵化的东西有助于编写更好的代码(阅读:更易于维护)。@AlexandreC.“销毁时取消订阅”在这里是不清楚的。如果你(双方)拥有通知程序,就永远不会有任何“销毁时取消订阅”。只要通知程序可用,析构函数就不会被调用,当析构函数被调用时,所有的通知程序都必须消失。那么在什么情况下会发生这种情况呢?@LiKao:无论如何,你应该努力避免相互依赖。观察者模式必须在存在循环的情况下进行处理,因为对象不能相互通知循环(无限递归)。记住这个警告,你必须设计避免那些循环依赖,这就是我在前面的评论中的意思:如果你保持代码简单,那么代码更易于维护。如果你需要更复杂的东西,那么你应该三思而后行(并使用完全不同的方法:垃圾收集或健壮的消息传递是可选的)在这种情况下,可能是最好的方法;谢谢。当然,我意识到我可能不能让通知程序使用智能指针,也不能让对象在构造时添加自己,因为在构造函数完成之前,对象的智能指针是“不可用”的。
class BodyChild : public Body {
  public:
    BodyChild(){
      Notifier<BodyMessage>::register(get_shared_ptr());
}
boost::shared_ptr<Child> p = static_pointer_cast<Child>(shared_from_this());