智能指针的原理
RAII
RAII(Resource Acquisition Is Initialization)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。
在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。 借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做法有两大好处:
1. 不需要显式地释放资源。
2. 采用这种方式,对象所需的资源在其生命期内始终保持有效。
并且,智能指针对象重载了*和->运算符,在用法上和原生指针一致。
c++中有三种智能指针:
auto_ptr
头文件:<memory>
auto_ptr使用:
#include <iostream>
#include <memory>
using namespace std;
struct Date
{
int year;
int mouth;
int day;
};
int main(int argc,char* argv[]) {
auto_ptr<Date> ap(new Date());
auto_ptr<Date> ap1(ap);
ap->year = 2021;
return 0;
}
执行结果:
失败的代码是:ap->year = 2021; 为什么此时访问ap的成员时会报错呢?我们来看看它们的地址。
我们发现在拷贝构造之后,sp管理的地址为空,而sp1管理的地址是之前sp所管理的地址,管理权发生了转移。那么上面所说的报错也很容易想通,因为sp管理的地址为空,不能进行访问。
auto_ptr的问题:当对象拷贝或者赋值后,管理权进行转移,造成前面的对象悬空。auto_ptr问题是非常明显的,所以实际中很多公司明确规定了不能使用auto_ptr。
unique_ptr
为了解决拷贝或者赋值时管理权转移的问题,出现了unique_ptr。
unique_ptr解决问题的方式非常粗暴:防拷贝,也就是不让赋值和拷贝
shared_ptr
shared_ptr是c++11中提出的更,解决了auto_ptr拷贝时所有权转移的问题和unique_ptr不能拷贝和赋值的问题。解决的关键就是增加了引用计数。
shared_ptr的原理:是通过引用计数的方式来实现多个shared_ptr对象之间共享资源。
1.shared_ptr在其内部,给每个资源都维护了着一份计数,用来记录该份资源被几个对象共享。
2. 在对象被销毁时(也就是析构函数调用),就说明自己不使用该资源了,对象的引用计数减一。
3. 如果引用计数是0,就说明自己是最后一个使用该资源的对象,必须释放该资源;
4. 如果不是0,就说明除了自己还有其他对象在使用该份资源,不能释放该资源,否则其他对象就成野指针了。
5. shared_ptr中成员函数:use_count(对象数据的引用计数)
shared_ptr使用
int main(int argc,char* argv[]) {
shared_ptr<Date> sp(new Date());
cout << sp.use_count() << endl; //1
shared_ptr<Date> sp1(sp);
cout << sp.use_count() << endl; //2
cout << sp1.use_count() << endl; //2
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)