【发布时间】:2016-05-30 19:19:13
【问题描述】:
通常,我会用weak_ptr 打破shared_ptrs 的循环。但在这个例子中我看不到如何做到这一点:
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 本身除外)拥有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 的 aliasing constructor (8) 或其他东西来完成一些技巧。
【问题讨论】:
-
隐藏的循环引用实际上无法用标准 c++
shared_ptr/weak_ptr成语解决。你必须改变你的设计。 -
由于
c和cache将始终相互引用,也许您应该创建一个包含Cache和C的新类C,并让C::cache和Cache::c使用它的引用计数 (std::shared_ptr<C>(cwd, &cwd->c))
标签: c++ shared-ptr reference-counting