栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++智能指针

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++智能指针

智能指针主要是为了解决内存忘记释放、内存过早释放、内存多次释放等问题,从而更好地对内存进行管理。(个人理解)

传统的裸指针虽然功能强大、使用灵活,但需要全程维护,容易出错。从而引入智能指针进行管理,可以把智能指针看做对于裸指针的包装。

智能指针有四种: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_ptr sptr(new int);
shared_ptr sptr1(new int(10));

int *p = new int();//值初始化
shared_ptr sptr2(p);//用裸指针也可以初始化,但是不推荐

2.使用make_shared()函数初始化

一般形式:

shared_ptr sptr = 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_ptr p1(new int(10));
shared_ptr p2(p1);
weak_ptr pw1(p1);
cout< 

2.reset():用于重置shared_ptr

shared_ptr p1(new int(10));
p1.reset();//不带参数情况,将p1置空
p1.reset();//带参数情况,一般输入为new出来的裸指针,此时p1指向新的内存

3.unique:判断此shared_ptr是否独占内存

        若独占,返回true,否则返回false。

shared_ptr p1 = make_shared (10);
if(p1.unique()) {//此只有p1一个shared_ptr指向该内存,所以unique()返回true
    cout<<"独占"< 

4.shared_ptr同样可以使用*解引用,方式同普通指针

5.get():返回shared_ptr中保存的裸指针

shard_ptr p1 = make_shared (10);
int *p = p1.get();//get()返回p1中的裸指针
cout<<*p< 

6.swap():交换两个shared_ptr指向

shared_ptr ps1 = 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_ptr ps1(new int[10], [](int *p){
    delete[] p;
});

8.使用shared_ptr维护数组时的几种方法

第一种:从C++17开始,shared_ptr的模板参数支持传入<数据类型[]>用于对于数组内存的管理,同时提供了operator[]用于对数组元素直接进行访问,在释放数组时会调用delete[]对内存进行释放。

shared_ptr p1(new int[]{1,2,3});//模板参数传入int[]
cout<>p1[1]< 

第二种:在C++17前,shared_ptr不支持模板参数传入<数据类型[]>,同时不支持operator[],系统在释放内存时会默认调用delete进行释放。因此当我们使用shared_ptr管理数组时,系统会在释放内存时使用delete而报错。

情况如下:

shared_ptr ps1(new int[3]{1,2,3));//使用shared_ptr管理数组
cout< 

对于这种情况有两种解决办法:

方法1:C++提供了一种标准库的类模板default_delete,可以用于数组内存的释放。可以在初始化shared_ptr时指定该删除器。

shared_ptr ps1(new int[10], default_delete());

方法2:自己定义删除器

void mydeleter(int *p) {
    delete[] p;//用delete[]释放数组内存
}

int main() {

    shared_ptr ps1(new int[10], mydeleter);//指定自己定义的删除器

    return 0;

}

注意:虽然两个shared_ptr指定的删除器可能不同,但只要它们指向同一个内存,那么它们就属于同一个类型。

水平有限,欢迎批评指正!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/316466.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号