智能指针主要是为了解决内存忘记释放、内存过早释放、内存多次释放等问题,从而更好地对内存进行管理。(个人理解)
传统的裸指针虽然功能强大、使用灵活,但需要全程维护,容易出错。从而引入智能指针进行管理,可以把智能指针看做对于裸指针的包装。
智能指针有四种:auto_ptr(c++98)、shared_ptr(c++11)、unique_ptr(c++11)、weak_ptr(c++11),其中auto_ptr已被unique_ptr替代,不推荐使用auto_ptr。
智能指针是一种类模板。
一、shared_ptr共享式指针
shared_ptr允许多个指针指向同一个对象(内存)。其采用引用计数的机制,每多一个shared_ptr指向该对象,引用计数加一,每少一个shared_ptr,引用计数减一。当引用计数为0时,会自动析构该对象(释放该内存)。
shared_ptr的定义形式:
shared_ptr智能指针名;//智能指针是类模板,需要使用<>指定参数类型(指针指向的类型)
shared_ptr的两种初始化方式:
1.使用new初始化
一般形式:
shared_ptrsptr(new int); shared_ptr sptr1(new int(10)); int *p = new int();//值初始化 shared_ptr sptr2(p);//用裸指针也可以初始化,但是不推荐
2.使用make_shared()函数初始化
一般形式:
shared_ptrsptr = make_shared (100);//make_shared是函数模板,所以需要使用<>指定参数类型 shared_ptr sptr = make_shared (5, 'a');//调用string的构造函数进行string的初始化
make_shared是一种函数模板。推荐使用make_shared()进行shared_ptr的初始化,其缺点是不能自定义删除器。
shared_ptr拓展
1.use_count():返回当前shared_ptr所指内存的强引用数即shared_ptr的个数
shared_ptrp1(new int(10)); shared_ptr p2(p1); weak_ptr pw1(p1); cout< 2.reset():用于重置shared_ptr
shared_ptrp1(new int(10)); p1.reset();//不带参数情况,将p1置空 p1.reset();//带参数情况,一般输入为new出来的裸指针,此时p1指向新的内存 3.unique:判断此shared_ptr是否独占内存
若独占,返回true,否则返回false。
shared_ptrp1 = make_shared (10); if(p1.unique()) {//此只有p1一个shared_ptr指向该内存,所以unique()返回true cout<<"独占"< 4.shared_ptr同样可以使用*解引用,方式同普通指针
5.get():返回shared_ptr中保存的裸指针
shard_ptrp1 = make_shared (10); int *p = p1.get();//get()返回p1中的裸指针 cout<<*p< 6.swap():交换两个shared_ptr指向
shared_ptrps1 = make_shared ("hello"); shared_ptr ps2 = make_shared ("world"); cout << *ps1 << endl << *ps2 << endl; swap(ps1, ps2);//交换两个指针指向的对象 ps1.swap(ps2);//交换两个指针指向 cout << *ps1 << endl << *ps2 << endl; 7.删除器
默认情况下,在内存的强引用计数减为0时,系统会调用delete()对内存进行释放。如果指定删除器,则系统会调用指定的删除器释放内存。
删除器形式一:函数
void mydeleter(int *p) { //代码实现 cout<<"自定义删除器"<p1(new int(10), mydeleter);//在参数列表中指定删除器 p1.reset();//p1置空,系统自动调用自定义删除器释放内存 return 0; } 删除器形式二:lambda表达式
shared_ptrps1(new int[10], [](int *p){ delete[] p; }); 8.使用shared_ptr维护数组时的几种方法
第一种:从C++17开始,shared_ptr的模板参数支持传入<数据类型[]>用于对于数组内存的管理,同时提供了operator[]用于对数组元素直接进行访问,在释放数组时会调用delete[]对内存进行释放。
shared_ptrp1(new int[]{1,2,3});//模板参数传入int[] cout< >p1[1]< 第二种:在C++17前,shared_ptr不支持模板参数传入<数据类型[]>,同时不支持operator[],系统在释放内存时会默认调用delete进行释放。因此当我们使用shared_ptr管理数组时,系统会在释放内存时使用delete而报错。
情况如下:
shared_ptrps1(new int[3]{1,2,3));//使用shared_ptr管理数组 cout< 对于这种情况有两种解决办法:
方法1:C++提供了一种标准库的类模板default_delete,可以用于数组内存的释放。可以在初始化shared_ptr时指定该删除器。
shared_ptrps1(new int[10], default_delete ()); 方法2:自己定义删除器
void mydeleter(int *p) { delete[] p;//用delete[]释放数组内存 } int main() { shared_ptrps1(new int[10], mydeleter);//指定自己定义的删除器 return 0; } 注意:虽然两个shared_ptr指定的删除器可能不同,但只要它们指向同一个内存,那么它们就属于同一个类型。
水平有限,欢迎批评指正!



