智能指针的种类以及使用场景
踩内存: 由于指针在使用的之前又被释放掉,那么这块内存很有可能又被分配出去了。参考踩内存
char* p = (char* )malloc(6); strcpy(p, "hello"); free(p); //当指针p释放内存后,该内存以后可以被存储其他数据 }
free
函数就是把这块内存和 p 之间的所有关系斩断,从此 p 和那块内存之间再无瓜葛。至于指针变量p本身保存的地址并没有改变,但是它对这个地址处的那块内存却已经没有所有权了。那块被释放的内存里面保存的值也没有改变,只是再也没有办法使用了。
shared_ptr 使用规范
暴露裸指针:
#include <iostream> #include <memory> using namespace std; int main() { int *p = new int(); shared_ptr<int> sp = shared_ptr<int>(p); //暴露了裸指针 shared_ptr<int> sp = shared_ptr<int>(new int); //隐藏了裸指针 shared_ptr<int> sp = make_shared<int>(); //其中维护了弱引用技术 int *p = sp.get(); //避免使用get方式获取指针 }
智能指针管理的对象将自身返回:
class T : public enable_shared_from_this<int> { public: shared_ptr<T> self() { return enable_shared_from_this(); } };
unique_ptr 使用规范
//此方式返回是可以的 #include <iostream> #include <memory> using namespace std; class T {}; unique_ptr<T> get_unique() { unique_ptr<T> up; return up; } int main() { unique_ptr<T> = get_unique(); return 0; } }
weak_ptr解决循环引用问题
循环引用
#include <iostream> #include <memory> using namespace std; class B; class A { public: ~A() { cout << "A::~A()" << endl; } shared_ptr<B> spb; }; class B { public: ~B() { cout << "B::~B()" << endl; } shared_ptr<A> spa; }; int main() { shared_ptr<A> sp1 = make_shared<A>(); shared_ptr<B> sp2 = make_shared<B>(); sp1->spb = sp2; sp2->spa = sp1; cout << "A.use_count():" << sp1.use_count() << " B.use_count():" << sp2.use_count() << endl; return 0; } //代码运行结果:A.use_count():2 B.use_count():2
利用weak_ptr解决
#include <iostream> #include <memory> using namespace std; class B; class A { public: ~A() { cout << "A::~A()" << endl; } weak_ptr<B> spb; }; class B { public: ~B() { cout << "B::~B()" << endl; } weak_ptr<A> spa; }; int main() { shared_ptr<A> sp1 = make_shared<A>(); shared_ptr<B> sp2 = make_shared<B>(); sp1->spb = sp2; //使用了weak_ptr后,在持有的过程中不会增加应用计数 sp2->spa = sp1; //使用了weak_ptr后,在持有的过程中不会增加应用计数 cout << "A.use_count():" << sp1.use_count() << " B.use_count():" << sp2.use_count() << endl; return 0; }
代码运行结果
A.use_count():1 B.use_count():1 B::~B() A::~A() 先构造类A对象,在构造类B对象,析构先析构B对象在析构A对象
将引用计数降为 1 ,且调用了各自析构函数。辅助 shared_ptr,用来解决 shared_ptr 循环引用,原理弱引用不占强引用计数
充电站
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习