使用带有循环引用的weak_ptr
Use of weak_ptr with cyclic references
所以我很难理解为什么我们必须使用weak_ptr
,尤其是对于循环引用问题,请考虑以下代码:
class B; //forward declaration
class A {
shared_ptr<B> b_ptr;
public:
void set_B(shared_ptr<B>& b)
{
b_ptr = b;
}
A() { cout << "A constructor" << endl; }
~A() { cout << "A destructor" << endl; }
};
class B {
shared_ptr<A> a_ptr;
public:
void set_A(shared_ptr<A>& a)
{
a_ptr = a;
}
B() { cout << "B constructor" << endl; }
~B() { cout << "B destructor" << endl; }
};
int main() {
shared_ptr<A> a = make_shared<A>();
shared_ptr<B> b = make_shared<B>();
a->set_B(b);
b->set_A(a);
}
现在从我听到的,当a
和b
都超出范围并且它们的引用计数为 0 时,它们会尝试释放并销毁指向内存的内容,但在这种情况下,它们无法做到这一点,因为两者都指向对象具有引用计数为 1 的shared_ptr
,这使得它们不可删除, 这是真的吗?
然后,它说要解决此问题,我必须使class B
中的shared_ptr
成为weak_ptr
,现在为什么呢? 它的引用计数仍然为 1,不是吗?即使有weak_ptr,仍然有引用计数为 1 的shared_ptr<B> b_ptr;
,那么如何删除它呢?
它还提到weak_ptr
破坏了强所有权引用,但weak_ptr怎么可能没有所有权,它将如何访问对象?
提前谢谢。
对于所有std::shared_ptr
,您有:
int main() {
std::shared_ptr<A> a = std::make_shared<A>(); // ref_count_a = 1
std::shared_ptr<B> b = std::make_shared<B>(); // ref_count_b = 1
a->set_B(b); // ref_count_b = 2
b->set_A(a); // ref_count_a = 2
} // ref_count_a = 1 && ref_count_b = 1
// memleak due to the cycle
跟
class B {
std::weak_ptr<A> a_ptr;
// ...
};
它变成:
int main() {
std::shared_ptr<A> a = std::make_shared<A>(); // ref_count_a = 1
std::shared_ptr<B> b = std::make_shared<B>(); // ref_count_b = 1
a->set_B(b); // ref_count_b = 2
b->set_A(a); // ref_count_a = 1 , weak_ref_a = 1
} // ref_count_a = 0 && ref_count_b = 1
// -> release a -> ref_count_b = 0
// -> release b (+ control block) -> weak_ref_a = 0
// -> release control block of a
它还提到weak_ptr破坏了强所有权引用,但weak_ptr怎么可能没有所有权,它将如何访问对象?
控件维护shared_ptr
的计数器(释放对象( 以及一个计数器,供weak_ptr
释放控制块。 weak_ptr通过控制块检索shared_ptr。
最后我听说weak_ptr是一个智能指针,可以使用 lock(( 或 expire(( 等方法来管理shared_ptr,这又是对的吗?
是的
相关文章:
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 这是MSVC 2013中具有共享PTR的单例的正确实现吗?
- 对唯一 ptr 无效读取的引用向量
- C++ 类型转换基础 PTR 到派生 PTR 保存在引用类中
- 为什么使用模板生成的函数具有"weak"符号类型?