如何打破这个std :: shared_ptr引用循环?

时间:2016-05-30 19:19:13

标签: c++ shared-ptr reference-counting

通常,我会用shared_ptr打破weak_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本身除外)都有Cacheshared_ptr<C>就需要保持活着,所以仅使用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的{​​{3}}(8)或其他东西来完成一些诡计。

1 个答案:

答案 0 :(得分:0)

  
    

&#34;只要任何人(缓存本身除外)都有shared_ptr<C>,缓存就需要保持活跃状态​​。&#34;

  

这证明C控制整个结构的最终寿命。 因此,不应该将缓存组成C?