C++ 智能指针

智能指针

 

在平常的内存空间分配中我们习惯于用new运算符来开辟一段我们想要的大小的内存空间,我们都知道用此开辟的堆中内存空间,在函数执行完之后要释放该部分内存,否则将会发生内存泄漏。有时候你可能忘记,有时也可能在不经意间删除或注释掉该代码,此时智能指针会对你有帮助。

智能指针是行为类似于指针的类对象,再次介绍三个可帮助管理动态内存分配的智能指针模板:

1.auto_ptr  //C++98提供的智能指针,C++11已经将其摒弃 

2.unique_ptr

3.shared_ptr

这三个智能指针模板都定义了类似指针的对象,可以将new获得的地址赋给这种对象,当智能指针过期时,其析构函数将使用delete来释放内存。要创建智能指针对象,必须包含<memory>头文件,智能指针模板位于std名称空间中。

如果ps是一个智能指针对象,则可以对他执行解引用操作(*ps),用它来访问结构体成员(ps->puff),将他赋给指向相同类型的常规指针,还可以将智能指针对象赋给另一个同类型的智能指针对象。

 

模板auto_ptr包含如下的构造函数:

所有的智能指针都有一个explicit构造函数,该构造函数将指针作为参数,因此不需要自动将指针转换为智能指针对象。

throw() 意味着构造函数不会引发异常,于auto_ptr一样,throw()也被C++11摒弃;

 

三种智能指针的创建方法与类型:

 

auto_ptr 和 unique_ptr 的差异:

看下面的语句:

语句3中,p2接管string对象的所有权后,p1的所有权将被剥夺。这可能是件好事,可以防止p1 和p2 的析构函数试图删除同一个对象;但如果程序随后试图使用p1, 这将是件坏事,因为p1不再指向有效数据,留下了危险的指针悬挂。

来看unique_ptr的情况:

编译器将认为语句3非法,避免了p2 不再指向有效数据的问题。因此unique_ptr比auto_ptr更加安全。(编译阶段错误比潜在的程序崩溃更安全)。

相比于auto_ptr,unique_ptr还有一个优点。它有一个可用于数组的变体。别忘了,必须将delete和new配对, 将delete[] 和new[]

配对。模板auto_ptr使用的是delete而不是delete[],因此只能于new一起使用,但unique_ptr有使用delete[] 和new[] 的版本。

std::unique_ptr<double []> pda(new double[5])。

 

C++还有一个标准库函数std::move(),让你能够将一个unique_ptr 赋给另一个。

 

 

shared_ptr

如果程序要使用多个指向同一个对象的指针,应选择shared_ptr。这样的情况包括:

1.有一个指针数组,并使用一些辅助指针来标识特定的元素,如最大的元素和最小的元素;

2.两个对象包含都指向第三个对象的指针;

3.STL容器包含指针.

 

在unique_ptr为右值时,可将其赋值给shared_ptr,模板shared_ptr包含显示构造函数,可用于将右值unique_str转换为shared_str,shared_ptr将接管原来归unique_ptr所有的对象。


头文件: <memory>
通过shared_ptr的构造函数,可以让shared_ptr对象托管一个new运算符返回的指针,写法如下:
shared_ptr<T> ptr(new T);      // T 可以是 int ,char, 类名等各种类型
此后ptr就可以像 T* 类型的指针一样来使用,即 *ptr 就是用new动态分配的那个对象,而且不必操心释放内存的事。
多个shared_ptr对象可以同时托管一个指针,系统会维护一个托管计数。当
无shared_ptr托管该指针时,delete该指针。

shared_ptr对象不能托管指向动态分配的数组的指针,否则程序运行会出错。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值