C++智能指针
来源:互联网 发布:阿里云 paas iaas 编辑:程序博客网 时间:2024/06/06 04:34
std::shared_ptr
初始化
构造函数初始化:
std::shared_ptr<int> p(new int(1));
std::make_shared< T >初始化
std::shared_ptr<int> p = std::make_shared<int>(1);
注意:不能将一个原始指针直接复制给一个智能指针。
std::shared_ptr<int> p = new int(1);//编译报错
获取原始指针
可以用get方法来返回原始指针。
std::shared_ptr<int> p(new int(1));int* ptr = p.get();
指定删除器
智能指针初始化可以指定删除器。
void DeleteIntPtr(int* p){ delete p;}std::shared_ptr<int> p(new int, DeleteIntPtr);
使用lambda表达式:
std::shared_ptr<int> p(new int, [](int* p){delete p};);
当使用shared_ptr管理动态数组是,需要指定删除器,因为其默认删除器不支持数组对象。
std::shared_ptr<int> p(new int[10], [](int* p){delete[] p};);
可以将std::default_delete作为删除器,其内部是通过调用delete实现的。
std::shared_ptr<int> p(new int[10], std::default_delete<int[]>);
使用shared_ptr需要注意的问题
- 不要用原始指针初始化多个shared_ptr
int* ptr=new int;std::shared_ptr<int> p1(ptr);std::shared_ptr<int> p2(ptr);//错误
- 不要在实参中创建shared_ptr
function(shared_ptr<int>(new int),g());//有缺陷
由于不同的编译器函数参数的计算顺序可能不同,可能先new int,然后调用g(),如果g()发生异常,shared_ptr< int >还没有创建,则int内存泄漏。正确写法应该先创建智能指针。
shared_ptr<int> p(new int());function(p, g());
- 通过shared_from_this()返回this指针,不要将this指针作为shared_ptr返回出来,否则会导致重复析构。
struct A{ shared_ptr<A> Getself(){ return shared_ptr<S>(this); }};int main(){ shared_ptr<A> sp1(new A); shared_ptr<A> sp2=sp1->Getself(); return 0;}
由于用同一个指针(this)构造了两个智能指针,所以会造成重复析构。
正确返回this 的shared_ptr的做法是:让目标类通过派生std::enable_shared_from_this< T >类,然后使用基类的成员函数shared_from_this()来返回。
class A:public std::enable_shared_from_this<A>{ std::shared_ptr<A> GetSelf(){ return shared_from_this(); }};std::shared_ptr<A> spy(new A);std::shared_ptr<A> p=spy->GetSelf();
- 避免循环引用
循环引用会导致内存泄漏,下面是一个典型的循环引用的场景:
struct A{ std::shared_ptr<B> bptr; ~A() { cout << "A is deleted!" << endl; }};struct B{ std::shared_ptr<A> aptr; ~B() { cout << "B is deleted!" << endl; }};void TestPtr(){ std::shared_ptr<A> ap(new A); std::shared_ptr<B> bp(new B); ap->bptr = bp; bp->aptr = ap;}
循环引用导致ap和bp的引用计数都为2,离开作用域后减为1,产生内存泄漏。
std::unique_ptr
unique_ptr不允许其他智能指针共享其内部的指针。
unique_ptr<T> myPtr(new T);unique_ptr<T> myOtherPtr=myPtr;//错误unique_ptr<T> myOtherPtr=std::move(myPtr);//可以移动
unique_ptr可以指向一个数组:
std::unique_ptr<int []>ptr(new int10[]);
unique_ptr指定删除器和shared_ptr有差别:
std::unique_ptr<int,void(*)(int*)>ptr(new int(1),[](int*p){delete p;});
std::weak_ptr
weak_ptr用来监视shared_ptr,不会使引用计数加1,不共享指针,不能操作资源。
基本用法
- 通过use_count()来获得当前观测资源的引用计数
shared_ptr<int> sp(new int(10));weak_ptr<int> wp(sp);cout<<wp.use_count()<<endl;//结果为1
- 通过expired()来判断观测的资源是否被释放
shared_ptr<int> sp(new int(10));weak_ptr<int> wp(sp);if(wp.expired()) cout<<"监视指针已被释放"<<endl;
- 通过lock()来获取监视的shared_ptr
std::weak_ptr<int> gw;void f(){ if (auto spt = gw.lock()) { std::cout << *spt << "\n"; } else { std::cout << "gw is expired\n"; }}int main(){ { auto sp = std::make_shared<int>(42); gw = sp; f(); } f();}
输出:
42gw is expired
weak_ptr解决循环引用
将A或B改为weak_ptr即可。
struct A{ std::shared_ptr<B> bptr; ~A() { cout << "A is deleted!" << endl; }};struct B{ std::weak_ptr<A> aptr; ~B() { cout << "B is deleted!" << endl; }};void TestPtr(){ std::shared_ptr<A> ap(new A); std::shared_ptr<B> bp(new B); ap->bptr = bp; bp->aptr = ap;}
阅读全文
1 0
- c++:智能指针
- C++:智能指针
- 【C++】智能指针
- 【C++】智能指针
- C++PJ智能指针
- 【c++】智能指针
- 【C++】智能指针auto_ptr
- C++,智能指针
- C++,boost智能指针
- 智能指针模拟C
- [C++]智能指针
- 【C++】 浅析智能指针
- C++_智能指针
- C++:初识智能指针
- C++::智能指针
- 【C++】智能指针
- c智能指针:unique_ptr
- 【C++】智能指针
- C:整型数据与字符型数据的存储问题
- 【Scikit-Learn 中文文档】内核岭回归
- 《设计模式》学习笔记3——工厂模式
- kotlin-命令行开发环境
- 栈
- C++智能指针
- PyQt5简单仪表盘
- [从C到C++] 1.3 C++布尔类型(bool)
- JPA规范介绍以及JPA、ORM框架以及Spring Data Jpa的关系
- 在RequestTracker(RT)里用msmtp通过远程smtp服务器465端口发邮件
- 【Android UI自动化测试】Java+appium+ADT+uiautomatorviewer+Android模拟器
- 11月20日云栖精选夜读:围观阿里总部:边喝茶边搞技术是一种怎样的体验?
- Android中的缓存策略--LruCache
- 规范word整理的HTML笔记~