做网站怎么买断源码,北京个人网站建设多少钱,好企业网站,网页制作工具及用途一#xff1a;背景 上一篇我们聊到了C 的 auto_ptr #xff0c;有朋友说已经在 C 17 中被弃用了#xff0c;感谢朋友提醒#xff0c;今天我们来聊一下 C 11 中引入的几个智能指针。unique_ptrshared_ptrweak_ptr看看它们都怎么玩。二#xff1a;三大智能指针详解 1. uniq… 一背景 上一篇我们聊到了C 的 auto_ptr 有朋友说已经在 C 17 中被弃用了感谢朋友提醒今天我们来聊一下 C 11 中引入的几个智能指针。unique_ptrshared_ptrweak_ptr看看它们都怎么玩。二三大智能指针详解 1. unique_ptr上一篇在说 auto_ptr 的时候聊过一个术语叫 控制权转移言外之意就是下面的代码会 访问违例 。void test() {int* i new int(10);auto_ptrint ptr1(i);auto_ptrint ptr2 ptr1; //将 ptr1 的控制台送给了 ptr2cout *ptr1 endl;
}int main() {test();
}这段代码用了赋值运算符可能是程序员的无心之举却引来程序的崩溃那能不能规避下这种 无心 的行为呢? 当然是可以的屏蔽掉 auto_ptr 中的赋值运算符不就可以了哈C 中的 unique_ptr 就是这么实现的可以看下源码。class unique_ptr {public:unique_ptr(const unique_ptr) delete;unique_ptr operator(const unique_ptr) delete;
};可以看到unique_ptr 将 复制构造函数 都给屏蔽了所以再硬写的话必然是报错。2. shared_ptr这个算是纯正的 引用计数高级语言中的 引用跟踪 经常会拿它做比较说它存在循环引用等各种问题。在循环引用之前先说下它的简单用法。void test() {int* i new int(10);shared_ptrint ptr1(i);shared_ptrint ptr2 ptr1;shared_ptrint ptr3 ptr2;printf(ptr.refcnt %d, ptr2.refcnt%d, ptr3.refcnt%d \n, ptr1.use_count(), ptr2.use_count(), ptr3.use_count());
}int main() {test();
}再看下源码大概在内部共同维护了对 _Ref_count_base 引用。class _Ref_count_base {
private:_Atomic_counter_t _Uses 1;_Atomic_counter_t _Weaks 1;
}很显然当所有的析构函数将 _Uses 降为 0 的时候就会对 i 进行释放参考源码如下class shared_ptr : public _Ptr_base_Ty {~shared_ptr() noexcept { // release resourcethis-_Decref();}
}class _Ref_count_base {void _Decref() noexcept { // decrement use countif (_MT_DECR(_Uses) 0) {_Destroy();_Decwref();}}
}原理大概摸清楚了接下来看下循环引用它最大的问题就是让 _Uses 永远也不会为 0#include iostream
#include stringusing namespace std;class BClass;class AClass
{
public:int i 10;shared_ptrBClass b;
};class BClass
{
public:int i 11;shared_ptrAClass a;
};void test() {AClass* a new AClass();BClass* b new BClass();shared_ptrAClass aclass(a);shared_ptrBClass bclass(b);aclass-b bclass;bclass-a aclass;printf(a.refcnt%d, b.refcnt%d, a%x,b%x \n, aclass.use_count(), bclass.use_count(), (*a), (*b));
}int main() {test();
}接下来可以在 main 方法结束的地方观察 a,b 所有的 heap 块的内存内容是否被释放? 可以清楚的看到还在那里。。. 如下图所示这就是 循环引用 造成的问题这时候就需要用到 weak_ptr 了。3. weak_ptr弱引用就是它的引用不改变对原对象中 _Uses 的引用接下来将 AClass 和 BClass 中的 shared_ptr 改成 weak_ptr 版。class AClass
{
public:int i 10;weak_ptrBClass b;
};class BClass
{
public:int i 11;weak_ptrAClass a;
};从图中可以看到此时 refcnt1, 再观察下地址 0x007f71a8 的内容可以发现已经被释放啦。好了今天我们就聊这么多希望对大家有帮助。