设为首页 加入收藏

TOP

C++拾遗--智能指针
2015-02-25 16:14:58 来源: 作者: 【 】 浏览:21
Tags:拾遗 智能 指针

前言


内存泄露是常见的问题,新标准中的智能指针从根本上解决了这个问题。所谓的智能指针,其智能性体现在:当没有对象使用某块动态分配的内存时,那就自动释放这片内存。


智能指针


下面这段程序可耗尽内存,导致程序崩溃。


#include
#include
using namespace std;


int main()
{
?while (1)
?{
? //每次动态分配80M内存
? double *p = new double[1024 * 1024 * 10];
? Sleep(2000);
?}
?return 0;
}


这就不运行了……


众所周知,动态分配的内存需要手动释放,每次分配80M,不用多久内存就会耗尽。


使用智能指针,就不会出现这种情况,如下


#include
#include
#include
using namespace std;


int main()
{
?while (1)
?{
? //每次分配800M内存
? shared_ptrp(new double[1024 * 1024 * 100]);
? Sleep(2000);
?}
?return 0;
}


运行后,观察内存使用情况,最多也只是在800M左右。


以上两例,粗略看出智能指针的安全性,不过这一切都建立在正确使用的前提下。下面来仔细探讨下标准库提供的智能指针的使用方法。


标准库中主要提供了两种智能指针:shared_ptr 和 unique_ptr。它们都是模板,主要区别是shared_ptr允许多个指针指向同一个对象,unique_ptr则独享一片内存。


共享操作
shared_ptr和unique_ptr都支持的操作


shared_ptr p, unique_ptr q 创建指向类型T的空智能指针
*p,解引用操作,获取它指向的对象,类型是T
p,将p当做条件判断,若p指向一个对象,则为true
p.get(),返回p指向对象的指针,类型是T*


shared_ptr
shared_ptr的独享操作


make_shared(arg_list); 返回一个shared_ptr,指向一个动态分配的类型为T的对象,并且使用arg_list初始化对象。
shared_ptrp(q); 把shared_ptr q拷贝赋值给p,此操作会增加q中的计数器
p = q; p的计数器减少,q的计数器增加
p.use_count(); 返回与p共享对象的智能指针数量
p.unique(); 若p.use_count()为1,返回true


代码演示


#include
#include
#include
#include
using namespace std;


int main()
{
?cout << "******shared_ptr演示***by David***" << endl;
?auto sp1 = make_shared(12);
?auto i1 = sp1.get();
?cout << typeid(i1).name() << endl;? ? //int *
?cout << "*sp1 = " << *sp1 << endl;
?auto sp2 = make_shared("zhangxiang");
?auto i2 = sp2.get();
?cout << typeid(i2).name() << endl;? ? //string *
?cout << "*sp2 = " << *sp2 << endl;
?auto i3 = *sp2;
?cout << typeid(i3).name() << endl;? ? //string
?auto sp3 = make_shared("David");
?cout << "sp2.unique() = " << sp2.unique() << endl;
?cout << "sp2.use_count() = " << sp2.use_count() << endl;
?cout << "sp3.use_count() = " << sp2.use_count() << endl;
?sp2 = sp3;
?cout << "sp2.use_count() = " << sp2.use_count() << endl;
?cout << "sp3.use_count() = " << sp2.use_count() << endl;
?cin.get();
?return 0;
}


运行



unique_ptr
unique_ptr独享一片内存,所以不支持拷贝和构造(有例外)


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇线程池的介绍及简单实现 下一篇Java装饰模式(Decorator模式)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: