智能指针的种类以及使用场景
踩内存: 由于指针在使用的之前又被释放掉,那么这块内存很有可能又被分配出去了。参考踩内存
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等技术内容,立即学习