存储指向自身的弱引用

14

我正在使用一个部分由一个喜欢为简单问题提供过度复杂解决方案的人实现的代码库(例如,仅为一对类型实例化的具有两个参数的模板类)。她做的一件事是在智能指针中创建对象,然后让该对象存储对自身的弱引用。

class MyClass {
    //...
    boost::weak_ptr<MyClass> m_self;
    //...
};

boost::shared_ptr<MyClass>
Factory::Factory::Factory::CreateMyClass() {
    boost::shared_ptr<MyClass> obj(new MyClass(...));
    boost::weak_ptr<MyClass> p(obj);
    obj->storeSelfPointer(p);
    return obj;
}

该类然后通过锁定m_self并传递生成的共享指针来使用它。

为了我自己的生命,我无法理解她试图实现什么。是否有一些模式或想法可以解释这个实现?在我看来,这完全没有意义,我想重构掉它。

编辑:我应该提到,使用从锁定m_self获得的结果智能指针的任何地方都没有保留智能指针。


6
我猜你不知道 std::shared_from_this - Ben Voigt
它是C++98,不使用更新的东西。 - James Davidoff
4
好的,这是 enable_shared_from_this 的 C++98 版本。 - Ben Voigt
1
请问你能详细说明一下“仅为一对类型实例化的具有两个参数的模板类”吗?还有Factory::Factory::Factory::是什么意思?这很有趣。 - Cheers and hth. - Alf
模板<class T,class U>类Foo;类Bar;类Biz;Foo仅作为Foo <Bar,Biz>使用;完全没有意义的行为泛化。 - James Davidoff
Factory::Factory::Factory是一个关于她对Java式过度使用模式的玩笑。要获取对象,您必须在工厂工厂工厂注册。 - James Davidoff
1个回答

19
这个“设计”的一个可能用途是使用m_self.lock()从此处生成共享指针。
如果删除这个弱指针成员,从this生成的共享指针所持有的引用计数将不正确。
它实现了与std::enable_shared_from_this相同的功能,有趣的是,cppreference.com提到了这个设计

启用enable_shared_from_this的常见实现是保持对此的弱引用(例如std::weak_ptr)。std::shared_ptr的构造函数检测到存在enable_shared_from_this基类,并将新创建的std::shared_ptr分配给内部存储的弱引用。

C++标准第20.8.2.4节10也提到了同样的实现方式:

创建唯一指针的shared_ptr构造函数可以检测到存在enable_shared_from_this基类,并将新创建的shared_ptr分配给其__weak_this成员


可能的重构:
  • 如果您正在使用C++11,则可以删除std::weak_ptr成员,并公开继承std::enable_shared_from_this<T>。您应该通过调用shared_from_this()从此处检索共享指针。
  • 如果您没有使用C++11但可以使用boost,则使用boost::enable_shared_from_this,请参见boost文档。您应该通过调用shared_from_this()从此处检索共享指针。
  • 如果您没有使用C++11并且无法使用boost,则可以将标准的建议实现引入到您的代码库中,它足够短:
代码:(从第20.8.2.4节-11复制,删除前导下划线,并且您可能需要重新命名它)
template<class T> class enable_shared_from_this {
    private:
     weak_ptr<T> __weak_this;
    protected:
     constexpr enable_shared_from_this() : __weak_this() { }
     enable_shared_from_this(enable_shared_from_this const &) { }
     enable_shared_from_this& operator=(enable_shared_from_this const &) { return *this; }
     ~enable_shared_from_this() { }
    public:
     shared_ptr<T> shared_from_this() { return shared_ptr<T>(__weak_this); }
     shared_ptr<T const> shared_from_this() const { return shared_ptr<T const>(__weak_this); }
};

使用 shared_from_this() 来创建一个 shared pointer。如果你复制此代码,请注意不能使用其他方式从 this 构造 shared pointers,那样不起作用。shared pointers 的构造函数需要修改(如标准引述所示)。


1
这不是官方文档。 - Ben Voigt
1
正确。实际上标准显示了完全相同的可能实现。 - quantdev
是的,我一直在尝试确认这个问题,但 PDF 搜索功能无法使用。现在我看到了。 - Ben Voigt
йҷ„еёҰеңЁйӮЈдёӘзӨәдҫӢдёӯзҡ„жіЁйҮҠйқһеёёйҮҚиҰҒ...еә“shared_ptrжҖҺд№ҲдјҡзҹҘйҒ“дҪ зҡ„enable_shared_from_thisе…ӢйҡҶдҪ“зҡ„еӯҳеңЁпјҢжӣҙдёҚз”ЁиҜҙи®ҝй—®е®ғзҡ„__weak_thisдәҶпјҹ - T.C.
@T.C.:是的,您不会在标准中看到这些功能,但是通过使用shared_from_this(),OP将保持其当前行为。通过其他方式从此创建shared_pointer仍然无法工作,而不修改shared_pointer构造函数,我会进行编辑... - quantdev
这个解释听起来很合理。我会给你打分,而且我会给她额外的加分,因为她实现了一个复杂的混乱代码,但并没有使用它;在锁定m_self之后,生成的shared_ptr通过const引用传递给各种函数,并且从未被复制或存储。换句话说,它被用作非常昂贵的this - James Davidoff

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