文档章节

使用对象来管理资源

Lennie002
 Lennie002
发布于 2015/10/17 22:32
字数 894
阅读 34
收藏 2
点赞 0
评论 0

熟悉智能指针的人肯定不会对此觉得陌生。利用C++中对象自动析构的特性,自动地释放资源。 C++编译器并未提供自动的垃圾回收机制,因此释放资源的责任落在了开发者的头上。 我们被要求总是成对地使用newdelete,例如:

Investment *pInv = createInvestment(); ... delete pInv;

createInvestment这样的方法属于工厂方法(factory function),用来创建一个对象的实例。

上述代码确实能够在不泄漏内存的情况下很好地执行,但问题出在createInvestment()函数把释放资源的责任交给了客户, 但并未显式地声明这一点,因而客户有时并不知情。即使客户知道该资源需要销毁, 也可能由于流控制语句或者异常的出现而使得资源未被及时释放。

幸运的是,我们可以用对象来包装资源,并在析构函数中释放它。这样客户便不需要维护资源的内存了。 std::auto_ptr便是这样一个对象,它被称为智能指针(smart pointer)。 典型的使用场景是,资源在堆空间中存储但只在局部被使用。

void f()
{   
     std::auto_ptr<Investment> pInv(createInvestment()); 
}

 

f()调用结束时pInv退出作用域,析构函数被调用,最终使得资源被释放。

 事实上,让createInvestment直接返回智能指针是更好的设计。 

可以看到,使用对象来管理资源的关键在于:创建资源后立即放入资源管理对象中,并利用资源管理对象的析构函数来确保资源被释放

资源管理对象的实现框架正是RAII原则:acquisition is initialization,用一个资源来初始化一个智能指针。指针的析构函数中释放资源。

值得注意的是,为了防止对象被多次释放,auto_ptr应当是不可复制的。

 复制一个auto_ptr会使它变成空,资源被交付给另一个只能指针。

std::auto_ptr<int> p1 (new int);
 *p1.get()=10; 
 std::auto_ptr<int> p2 (p1); 
 std::cout << "p2 points to " << *p2 << '\n'; 
 // p2 points to 10 
 // (p1 is now null-pointer auto_ptr)

.get方法返回资源的指针。

auto_ptr古怪的复制行为导致它并不是管理资源的最佳方式,甚至在STL中auto_ptr的容器也是不允许的: 可以创建这样的容器,但往里面添加元素(例如push_back)时会导致编译错。

auto_ptr<int> p1(new int); vector<auto_ptr<int>> v;    
// OK,可以编译 v.push_back(p1);            
// 编译错!

此处我们引入一个引用计数(reference-counting smart pointer,RCSP)的指针shared_ptr 它在没有任何其他指针引用到该资源时,进行资源的释放。不同于垃圾回收器,shared_ptr未能解决环状引用的问题。

值得注意的是auto_ptrshared_ptr只能管理单个资源,因为它们是使用delete而非delete[]来实现资源释放的。常见的错误便是传递数组进去:

std::tr1::shared_ptr<int> spi(new int[1024]);

在最新的C++标准中,智能指针已经归入std命名空间了。我们可以这样使用:std::shared_ptr<int>

虽然智能指针有这样的问题,但C++并未提供管理数组的智能指针,因为vector等容器就可以很好地完成这个工作。 如果你真的需要,可以求助与Boost社区的boost::scoped_arrayboost::shared_array

 

© 著作权归作者所有

共有 人打赏支持
Lennie002
粉丝 8
博文 93
码字总数 63011
作品 0
大连
Java EE 7 并发编程—Concurrency Utilities

Executor API的相关介绍可以在由Oracle维护的Java SE文档——High Level Concurrency Objects中找到。Executor API向开发者提供一系列的对象实现高效的线程管理。通常来说,这种高效是由一些...

旋转木马-千里马 ⋅ 2016/01/19 ⋅ 0

windows server 2016 活动目录(二)

AD对象 AD对象类型 用户 在AD域默认可以登陆任何具备信任关系的域中的计算机 访问应用,服务运行账户 访问网络资源(SSO) 默认加入域中的计算机,被域用户登陆后,在访问资源时,默认使用登...

haitao0228 ⋅ 04/20 ⋅ 0

SQL Server 2008最直观的变化下(四)

继续来总结SQL Server 2008的直观变化。 6,SQL Server 2008引入了“对象资源管理器详细信息”代替了SQL Server 2005的“摘要”,当在SQL Server Management Studio中的对象资源管理器中选择...

terryli ⋅ 2011/01/14 ⋅ 0

Effective C++ 资源管理小结

我发现,第一遍读书总是不能清楚的认识到问题的本质,我们还需要回过头去总结,因此,我决定以后每读一部分的书,写一点的总结,一方面可以让自己整理知识,另一方面方便以后对比思想。 资源...

长平狐 ⋅ 2012/11/12 ⋅ 0

C++智能指针的分析与使用

手动管理的弊端 在简单的程序中,我们不大可能忘记释放 new 出来的指针,但是随着程序规模的增大,我们忘了 delete 的概率也随之增大。在 C++ 中 new 出来的指针,赋值意味着引用的传递,当赋...

Tanswer_ ⋅ 01/11 ⋅ 0

《Effective C++》 读书笔记之三 资源管理

《Effective C++》 读书笔记之三 资源管理 准备知识: 所谓资源就是,一旦用了它,将来必须还给系统。最常用的资源是动态分配内存,其他常见的资源有文件描述器、互斥锁、图形界面的字形和笔...

wbf961127 ⋅ 2017/11/14 ⋅ 0

c++ 智能指针及 循环引用问题

c++智能指针介绍 由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete,比如流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不...

gfsfg8545 ⋅ 2014/04/07 ⋅ 0

Nebula3资源子系统

跟N2比起来, N3的资源子系统更加开放, 让程序员对资源的创建和管理更多的控制. Nebula3的资源有下面几个特性: 包装了一些其它Nebula子系统需要的数据 可以用ResourceId共享 可以在任何时候加...

长平狐 ⋅ 2012/11/12 ⋅ 0

C# vs C++之二:GC vs RAII

C# vs C++之二:GC vs RAII 资源管理 C中资源管理极为繁琐易错,大多复杂C系统都面临内存泄露、悬挂指针等问题 一方面由底层语言特点决定;另一方面也由于C语言特性相对较少,严重依赖程序员...

ddatsh ⋅ 2011/06/28 ⋅ 6

spring IOC/DI容器的理解

参与者:应用程序和spring 正向:现在的程序方向,A对象要使用B对象,现在是A里面直接创建B的实例,然后调用。 publc class A{ void t1(){ new B().t2(); } } public class B{ void t2(); 简...

君辰 ⋅ 2015/08/01 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Centos7重置Mysql 8.0.1 root 密码

问题产生背景: 安装完 最新版的 mysql8.0.1后忘记了密码,向重置root密码;找了网上好多资料都不尽相同,根据自己的问题总结如下: 第一步:修改配置文件免密码登录mysql vim /etc/my.cnf 1...

豆花饭烧土豆 ⋅ 今天 ⋅ 0

熊掌号收录比例对于网站原创数据排名的影响[图]

从去年下半年开始,我在写博客了,因为我觉得业余写写博客也还是很不错的,但是从2017年下半年开始,百度已经推出了原创保护功能和熊掌号平台,为此,我也提交了不少以前的老数据,而这些历史...

原创小博客 ⋅ 今天 ⋅ 0

LVM讲解、磁盘故障小案例

LVM LVM就是动态卷管理,可以将多个硬盘和硬盘分区做成一个逻辑卷,并把这个逻辑卷作为一个整体来统一管理,动态对分区进行扩缩空间大小,安全快捷方便管理。 1.新建分区,更改类型为8e 即L...

蛋黄Yolks ⋅ 今天 ⋅ 0

Hadoop Yarn调度器的选择和使用

一、引言 Yarn在Hadoop的生态系统中担任了资源管理和任务调度的角色。在讨论其构造器之前先简单了解一下Yarn的架构。 上图是Yarn的基本架构,其中ResourceManager是整个架构的核心组件,它负...

p柯西 ⋅ 今天 ⋅ 0

uWSGI + Django @ Ubuntu

创建 Django App Project 创建后, 可以看到路径下有一个wsgi.py的问题 uWSGI运行 直接命令行运行 利用如下命令, 可直接访问 uwsgi --http :8080 --wsgi-file dj/wsgi.py 配置文件 & 运行 [u...

袁祾 ⋅ 今天 ⋅ 0

JVM堆的理解

在JVM中,我们经常提到的就是堆了,堆确实很重要,其实,除了堆之外,还有几个重要的模块,看下图: 大 多数情况下,我们并不需要关心JVM的底层,但是如果了解它的话,对于我们系统调优是非常...

不羁之后 ⋅ 昨天 ⋅ 0

推荐:并发情况下:Java HashMap 形成死循环的原因

在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race Condition,从而导致死循环。这个事情我4、5年前也经历...

码代码的小司机 ⋅ 昨天 ⋅ 2

聊聊spring cloud gateway的RetryGatewayFilter

序 本文主要研究一下spring cloud gateway的RetryGatewayFilter GatewayAutoConfiguration spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/config/G......

go4it ⋅ 昨天 ⋅ 0

创建新用户和授予MySQL中的权限教程

导读 MySQL是一个开源数据库管理软件,可帮助用户存储,组织和以后检索数据。 它有多种选项来授予特定用户在表和数据库中的细微的权限 - 本教程将简要介绍一些选项。 如何创建新用户 在MySQL...

问题终结者 ⋅ 昨天 ⋅ 0

android -------- 颜色的半透明效果配置

最近有朋友问我 Android 背景颜色的半透明效果配置,我网上看资料,总结了一下, 开发中也是常常遇到的,所以来写篇博客 常用的颜色值格式有: RGB ARGB RRGGBB AARRGGBB 这4种 透明度 透明度...

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部