c++ - 我怎样才能打破这个 std::shared_ptr 引用循环?

标签 c++ shared-ptr reference-counting

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

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;
};

A 之间从来没有任何循环, B等。唯一的循环是对 Cache 的反向引用。 . Cache只要任何人(Cache 本身除外)拥有shared_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 来完成一些技巧。的 aliasing constructor (8) 什么的。

最佳答案

"The Cache needs to stay alive as long as anybody (except the Cache itself) has a shared_ptr<C>."

这表明 C 控制着整个结构的最终生命周期。 所以缓存是不是应该写成C?

关于c++ - 我怎样才能打破这个 std::shared_ptr 引用循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37532408/

相关文章:

c++ - 二维数组的静默运行时错误

c++ - 是否有必要释放 shared_ptr?

c++ - 有共享引用计数智能指针这样的东西吗?

PHP null 和写时复制

javascript - 了解垃圾回收引用计数方法中的交叉引用

c++ - 如果析构函数有副作用并且对象是从另一个静态对象的析构函数访问的,如何进行静态反初始化?

c++ - 如何从 std::istream 中读取数据(使用运算符>>)?

c++ - Boost dijkstra shortest_path - 如何获得最短路径而不仅仅是距离?

c++ - 使用智能指针管理缓冲区

c++ - 按值捕获 shared_ptr 的 lambda 如何影响它的 use_count()?