康定网站建设公司,江西建筑人才网招聘,做翻译 英文网站,购物网站设计图C智能指针一、智能指针的作用上一篇介绍了内存池的原理和实现#xff0c;详情请见内存池设计与实现#xff1b;内存池可以帮助我们有效的对内存进行管理#xff0c;智能指针可以很方便的管理指针#xff0c;避免出现内存泄漏#xff1b;智能指针的作用智能指针的作用… C智能指针一、智能指针的作用上一篇介绍了内存池的原理和实现详情请见内存池设计与实现内存池可以帮助我们有效的对内存进行管理智能指针可以很方便的管理指针避免出现内存泄漏智能指针的作用智能指针的作用智能指针可以帮助我们避免在申请空间后忘记释放造成内存泄漏的问题因为智能指针本身是一个类(后面也会自己实现一下)当出了类的作用域的时候类会调用析构函数进行释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间不需要手动释放内存空间。二、智能指针的原理我们这里的指针指针主要指的是shared_ptr,这也是一种引用计数型智能指针引用计数顾名思义就是在内存中记录有多少个智能指针被引用新增一个引用计数加一过期引用计数则减一当引用计数为0的时候智能指针才会释放资源案例一#include #include using namespace std;class A{public: A() { cout A Constructor endl; } ~A() { cout A Destruct endl; }};int main(){ shared_ptr p make_shared();cout count:endl;return 0;}结果rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# ./test1 A Constructorcount:1A Destruct我们再增加一个传参看一下引用计数案例二#include #include using namespace std;class A{public: A() { cout A Constructor endl; } ~A() { cout A Destruct endl; }};void fun(shared_ptrp){ coutfun count:endl;}int main(){shared_ptr p make_shared();cout count:endl; fun(p);cout count:endl;return 0;}结果rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# ./test1 A Constructorcount:1fun count:2count:1A Destruct通过上面的两个例子我们验证了最开始说的智能指针本身是一个类(后面也会自己实现一下)当出了类的作用域的时候类会调用析构函数进行释放资源三、智能指针的使用智能指针的使用比较简单在我们程序中需要包含头文件#include 注意智能指针是C11 的标准在编译的时候需要加上 -stdc11 的编译参数使用智能指针初始化有几种方式new和make_shared这里推荐使用make_shared原因是make_shared标准库函数是最安全的分配和使用动态内存的方法此函数在动态内存中分配一个对象并初始化它返回指向此对象的shared_ptr头文件和share_ptr相同。简单给个案例案例三#include #include using namespace std;class A{public: A(int count) { _nCount count; } ~A(){} void Print(){ coutcount:_ncountendl; }private:int _nCount;};int main(){ shared_ptrp make_shared(10); p-Print();return 0;}编译过程;rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# g -stdc11 test2.cpp -o test2rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# ./test2count:10四、智能指针使用注意项我们先来看一段代码案例四#include #include using namespace std;class B;class A{public: shared_ptr_pb;};class B{public:shared_ptr_pa;};int main(){shared_ptrpa make_shared();shared_ptrpb make_shared();coutpa count:endl;coutpb count:endl; pa-_pb pb; pb-_pa pa;coutpa count:endl;coutpb count:endl;return 0;}结果;rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# g -stdc11 test3.cpp -o test3rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# ./test3pa count:1pb count:1pa count:2pb count:2会发现最终的引用计数为2那么结束后引用计数不为0他们在堆上的空间不会被释放这就是常说的循环引用当然这不是无解的我们可以另外一种只能指针只不过这是种弱指针---weak_ptr,这种指针不会增加引用计数配合shared_ptr,可谓是郎才女貌皆大欢喜呀案例五#include #include using namespace std;class B;class A{public: weak_ptr_pb;};class B{public: weak_ptr_pa;};int main(){shared_ptrpa make_shared();shared_ptrpb make_shared();coutpa count:endl;coutpb count:endl; pa-_pb pb; pb-_pa pa;coutpa count:endl;coutpb count:endl;return 0;}结果rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# g -stdc11 test3.cpp -o test3rootiZuf67on1pthsuih96udyfZ:~/C/Net_C/demo4# ./test3pa count:1pb count:1pa count:1pb count:1很清晰的发现在最后互相引用的时候引用计数器没有加一最后出作用域的时候就会调用析构函数进行内存释放五、智能指针的实现实现智能指针无论是在面试还是深刻理解智能指针方面对我们帮助都是非常大的理解了上面的原理我们动手实现一个智能指针智能指针实现代码#include using namespace std;templateclass Tclass SmartPoint{public: //构造函数 SmartPoint(T* pNULL) { _ptr p; if (p ! NULL) { _count 1; } else { _count 0; } } //析构函数 ~SmartPoint() { if (--_count 0) { delete _ptr; } } //拷贝构造函数 SmartPoint(const SmartPoint src) { if (this ! src) { _ptr src._ptr; _count src._count; _count; } } //重载赋值操作符 SmartPoint operator(const SmartPoint src) { if (_ptr src._ptr) { return *this; } if (_ptr) { _count--; if (_count 0) { delete _ptr; } } _ptr src._ptr; _count src._count; _count; return *this; } //重载操作符 T* operator -() { if (_ptr) return _ptr; } //重载操作符 T operator *() { if (_ptr) return *_ptr; } size_t use_count() { return _count; }private: T* _ptr; size_t _count;};void Use(SmartPointchar p){ int n p.use_count();}int main(){ SmartPointcharsp1(new char); Use(sp1); SmartPointcharsp2(sp1); SmartPointcharsp3; sp3 sp1; int n sp1.use_count(); return 0;}往期精彩文章推荐内存池设计与实现恭喜你发现宝藏一份--技术文章汇总C11 计时器真香我们需要懂得CMake文件想了解学习更多C后台服务器方面的知识请关注微信公众号**CPP后台服务器开发**扫码CPP后台服务器开发转载是一种动力 分享是一种美德