我怎样才能打破这个标准::shared_ptr参考循环

How can I break this std::shared_ptr reference cycle?

本文关键字:shared 标准 ptr 循环 参考      更新时间:2023-10-16

通常,我会用weak_ptr打破shared_ptr s的循环。 但是在这个例子中我看不到如何做到这一点:

struct A;
struct B;
struct C;
struct D;
struct Cache {
    std::shared_ptr<A> a;
    std::shared_ptr<B> b;
    std::shared_ptr<C> c;
    std::shared_ptr<D> d;
};
struct A {
};
struct B {
    // Same 'a' as in the Cache
    std::shared_ptr<A> a;
};
struct C {
    // Holds a backreference to the cache
    std::shared_ptr<Cache> cache;
};
struct D {
    // Same 'c' as in the cache
    std::shared_ptr<C> c;
};

AB等之间从来没有任何循环。 唯一的循环是对Cache的反向引用。 只要任何人(除了Cache本身)有shared_ptr<C>Cache就需要保持生命,所以仅仅使用weak_ptr<Cache>是行不通的。 例如:

std::shared_ptr<Cache> make_cache() {
    auto cache = std::make_shared<Cache>();
    cache->a = std::make_shared<A>();
    cache->b = std::make_shared<B>();
    cache->b->a = cache->a;
    cache->c = std::make_shared<C>();
    cache->c->cache = cache;
    cache->d = std::make_shared<D>();
    cache->d->c = cache->c;
    return cache;
}
void use_cache() {
    auto a = make_cache()->a;
    // No need to keep the Cache around
    auto b = make_cache()->b;
    // b->a must be valid
    auto c = make_cache()->c;
    // c->cache must be valid
    auto d = make_cache()->d;
    // d->c (and therefore d->c->cache, etc.) must be valid
}

我知道一般来说这需要一个垃圾收集器,但我希望在这种特定情况下,可以使用shared_ptr的别名构造函数 (8) 或其他东西来完成一些技巧。

"只要任何人(缓存本身除外)有shared_ptr<C>,缓存就需要保持活动状态。"

这认为C控制了整个结构的最终寿命。因此,缓存不应该组合成 C 吗?