【C++】智能指针
智能指针
文章目录
- 智能指针
- 智能指针介绍
- unique_ptr
- shared_ptr
- weak_ptr
- 前置知识
》》普通指针
智能指针介绍
智能指针可以帮助C++程序员管理动态分配的内存的,它会帮助我们自动释放new出来的内存,从而避免内存泄漏!
智能指针不是指针,是一个管理指针的类,用来存储指向动态分配对象的指针,负责自动释放动态分配的对象,防止堆内存泄漏。
动态分配的资源,交给一个类对象去管理,当类对象声明周期结束时,自动调用析构函数释放资源
C++11后auto_ptr 已经被“抛弃”,改为unique_ptr替代!C++11后不建议使用auto_ptr,因此本位不从unique_ptr开始介绍
- 头文件
#include<memory>
- 创建
同模板类
unique_ptr<string> p1(new string("hello"));
shared_ptr<int>p2(new int(5));
API:
- get()获取智能指针托管的指针地址
unique_ptr<string> p1(new string("hello"));
cout << p1.get() << endl;
//0x55fade17eeb0
- release() 取消智能指针对动态内存的托管
unique_ptr<int>p1(new int(5));
int*pp = p1.release();
delete pp;//因为智能指针内部源码使用new所以这里可用delete
unique_ptr
两个指针不能指向同一个资源,复制或赋值都会改变资源的所有权。
无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值
保存指向某个对象的指针,当它本身离开作用域时会自动释放它指向的对象。
unique_ptr<int>p1(new int(5));
unique_ptr<int>p2(new int(6));
// p1 = p2; //禁止
// unique_ptr<int> p3(p1);//禁止
unique_ptr<int> p3(move(p1)); //move可以
p1 = move(p2);
- STL使用
vector<unique_ptr<int>> v;
unique_ptr<int> ptr1 (new int (5));
v.push_back(move(ptr1));
- 数组使用
nique_ptr<int[]> array(new int[5]);
shared_ptr
shared_ptr记录引用特定内存对象的智能指针数量,当复制或拷贝时,引用计数加1,当智能指针析构时,引用计数减1,如果计数为零,代表已经没有指针指向这块内存,就释放它
shared_ptr<int>p1(new int(5));
shared_ptr<int>p2(new int(6));
shared_ptr<int>p3(p1);
//使用make_shared 初始化对象,分配内存效率更高
//make_shared函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr
shared_ptr<int> p4 = make_shared<int>(7);
cout << *p3; //5
p3 = p2;
cout << *p3; //6
- use_count()可以获得当前托管指针的引用计数
cout << p3.use_count(); //2
- 循环引用问题
struct Father{
shared_ptr<Son> son_;
};
struct Son{
shared_ptr<Father> father_;
};
int main()
{
auto father = make_shared<Father>();
auto son = make_shared<Son>();
father->son_ = son;
son->father_ = father;
return 0;
}
互相持有导致循环引用问题,析构函数不能正常使用
weak_ptr
weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少。 同时weak_ptr 没有重载*和->但可以使用 lock 获得一个可用的 shared_ptr 对象。
shared_ptr<int>p1(new int(5));
weak_ptr<int>p2(p1);
cout << p1.use_count() << endl; //1
cout << p2.use_count() << endl; //1
cout << *p2 << endl; //错误
- 使用 lock 获得一个可用的 shared_ptr 对象
weak_ptr<int>p2(p1);
shared_ptr<int>p3 = p2.lock();
- weak_ptr解决循环引用问题
struct Father{
shared_ptr<Son> son_;
};
struct Son{
weak_ptr<Father> father_;
};
int main()
{
auto father = make_shared<Father>();
auto son = make_shared<Son>();
father->son_ = son;
son->father_ = father;
return 0;
}
我们在会产生循环引用的位置,把shared_ptr换成weak_ptr。它不参与资源的管理,他是专门用来解决引用计数的,我们可以使用一个shared_ptr 来初始化一个weak_ptr,但是weak_ptr 不增加引用计数,不参与管理,但是也像指针一样访问修改资源。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!