c++ - 一个非常弱的引用(不能变成共享)

标签 c++ shared-ptr weak-references

我想知道是否有实现“非常弱引用”思想的智能指针类型概念。

这基本上是一个 weak_ptr 但它不能变成一个 shared_ptr,基本上,当你有 very_weak_refs 时,你确保强引用计数永远不会增加。

这将允许管理器更好地“强所有权”内存,并且在野外提供非常弱的引用仍然允许客户端通过 .lock_get() 使用良好的旧原始指针访问数据> 函数或等同物...(名称旨在反射(reflect)您通常会做的事情 .lock().get())。

您在数据上没有相同的安全性,因为您的对象可能在您使用它时被销毁,但如果您的环境受到足够的控制,以至于您知道管理器无法在您处理时清除其数据,那么您在 lock_get() 之后检查了 null_ptr 之后,仍然可以在本地使用原始指针。

你们中有没有人想要类似的东西,更多的信息/情报/想法? 谢谢。

基本原理:背后的动机是 weak_ptr 具有可转为共享的“安全缺陷”,因此,在野外分发弱引用后,您基本上与分发共享引用相同,因为任何人都可以在您的数据上保留长期存在的共享引用,从而有效地阻止被认为是强大的实体(经理)进行正确清理。

这可以通过非常弱的引用来解决,当您在管理器的公共(public)界面中分发此类对象时,您可以确定当您删除最后一个共享引用时,您的数据也会被删除。

对我来说,弱引用的整个概念只适用于表现良好的客户;谁知道他们应该只在少量时间内将他们的弱引用提升到共享中。

最佳答案

不幸的是,传统的智能指针界面无法满足您的要求。

问题是终身的。 weak_ptr不能用于直接访问对象,因为它不能保证所述对象会存在足够长的时间:对象可能会从你的脚下被拉走。

例子:

int main() {
    std::shared_ptr<int> sp(new int(4));
    std::weak_ptr<int> wp(sp);

    if (not wp.expired()) {
        sp.reset();
        std::cout << *wp << "\n"; // Access WP ? But there is nothing there!
    }
}

因此,无论好坏,别无选择,只能在您实际需要访问对象时从弱指针中恢复共享指针而不控制此访问的持续时间.


然而,最后一点是我们的线索。一个简单的想法是编写一个行为良好的客户端 weak_ptr自己并改变它允许外部世界访问数据的方式。例如:

template <typename T>
class very_weak_ptr {
public:
    very_weak_ptr() {}

    explicit very_weak_ptr(std::weak_ptr<T> wp): _wp(wp) {}

    template <typename F>
    void apply(F&& f) {
        std::shared_ptr<T> sp = _wp.lock();
        f(sp.get());
    }

private:
    std::weak_ptr<T> _wp;
}; // class very_weak_ptr

注意:还有一个缺陷,enable_shared_from_this允许恢复 std::shared_ptr<T>来自 T 的实例;您可以在 T 上添加编译时检查以防止将此类与此类对象一起使用。

关于c++ - 一个非常弱的引用(不能变成共享),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20345646/

相关文章:

c++ - 前或后测试循环?

构造函数中的 C++ 二维数据数组 - 何时初始化和删除?

c++ - 我应该从使用 boost::shared_ptr 切换到 std::shared_ptr 吗?

language-agnostic - 弱引用的其他用途?

java - 如何知道与 WeakHashMap 中已删除条目关联的值

c++ - C++中删除数组中的对象

c++ - 编译后的二进制文件是 'munched'是什么意思?

c++ - 即使正确使用 make_shared,shared_from_this() 也会导致 std::bad_weak_ptr

c++ - 从声明为 std::set<std::shared_ptr<Edge>> edges_ 的 edges_ 中删除边;

Java GC : How does Java GC clears WeakReference object?