以对象管理资源的观念常被称为“资源取得时机便是初始化时机”(RAII)

auto_ptr被销毁时会自动删除它所指之物,所以一定要注意别让多个auto_ptr同时指向同一对象,否则对象会被删除多次,行为未定义

auto_ptr有一个性质:若通过拷贝构造函数或拷贝赋值运算符复制它们,它们会变成NULL,而复制所得的指针将取得资源的唯一拥有权

class Investment
{
private:double value;
public:Investment(double val):value(val){}double getValue(){return value;}
};Investment* createInvestment(double val)
{return new Investment(val);
}int main()
{auto_ptr<Investment> pInv1(createInvestment(3.0));cout << pInv1->getValue() << endl;auto_ptr<Investment>pInv2(pInv1);cout << pInv1->getValue() << endl;//出错,pInv1为NULL
}

可以用shared_ptr来代替auto_ptr,shared_ptr有一个缺点:无法打破环状引用,若两个其实已经没被使用的对象彼此互指,就好像还处在被使用的状态

auto_ptr和shared_ptr两者都在其析构函数内做delete而不是delete[]动作,所以在动态分配而得的array身上使用auto_ptr或shared_ptr是个馊主意

总结:

1.为防止资源泄露,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源

2.两个常被使用的RAII classes是shared_ptr和auto_ptr,前者是更好的选择(两者均用于管理heap上资源)

use shared_ptr with an array: https://stackoverflow.com/questions/13061979/shared-ptr-to-an-array-should-it-be-used

template<typename T >
struct array_deleter {  // 仿函数void operator ()( T const * p) {cout << "deleting" << endl;delete[] p;}
};int main()
{std::shared_ptr<int> sp( new int[10], array_deleter<int>() );system("pause");return 0;
}


class Lock
{
public:explicit Lock(mutex* pm) :mutexPtr(pm){mutexPtr->lock();}~Lock(){mutexPtr->unlock();}
private:mutex *mutexPtr;
};
----------------------------------------------------------------------------
//对底层资源采用引用计数
class Lock
{
public:explicit Lock(mutex* pm) :mutexPtr(pm,pm->unlock){mutexPtr.get()->lock();}
private:tr1::shared_ptr<mutex> mutexPtr;
};

shared_ptr允许指定删除器(deleter),这是一个函数或函数对象,当引用次数为0时便被调用(此机能并不存在于auto_ptr,它总是将指针删除)


在资源管理类中提供对原始资源访问的方法(即将RAII class对象转换为其所内含的原始资源):显式转换和隐式转换

显式转换:shared_ptr 和auto_ptr提供get成员函数,用来执行显式转换,返回智能指针内部的原始指针

隐式转换:shared_ptr和auto_ptr重载了指针取值操作符(operator->和operator*),它们允许隐式转换至底部原始指针

RAII class内的返回原始资源的函数与封装性发生矛盾,不过这并不要紧。RAII class并不是为了封装某物存在,它们的存在是为了确保资源释放会发生


成对使用new和delete时要采取相同形式。当class含有一个指针指向动态分配内存,并提供多个构造函数时,这种情况下你必须在所有构造函数中使用相同形式的new将指针成员初始化。如果没这样做,无法确定在析构函数中使用什么形式的delete。

shared_ptr构造函数是个explicit构造函数,无法进行隐式转换

以独立语句将newed对象存储于智能指针内,如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。在资源被创建和资源被转换为资源管理对象两个时间点之间可能发生异常干扰(条款17)


shared_ptr与weak_ptr智能指针均是C++ RAII的一种应用,可用于动态资源管理

shared_ptr基于“引用计数”模型实现,多个shared_ptr可指向同一个动态对象,并维护了一个共享的引用计数器,记录了引用同一对象的shared_ptr实例的数量。当最后一个指向动态对象的shared_ptr销毁时,会自动销毁其所指对象(通过delete操作符)。

shared_ptr的默认能力是管理动态内存,但支持自定义的Deleter以实现个性化的资源释放动作。

weak_ptr用于解决“引用计数”模型循环依赖问题,weak_ptr指向一个对象,并不增减该对象的引用计数器

weak_ptr用于配合shared_ptr使用,并不影响动态对象的生命周期,即其存在与否并不影响对象的引用计数器。

weak_ptr并没有重载operator->和operator *操作符,因此不可直接通过weak_ptr使用对象。

提供了expired()与lock()成员函数,前者用于判断weak_ptr指向的对象是否已被销毁,后者返回其所指对象的shared_ptr智能指针(对象销毁时返回”空“shared_ptr)。

转载于:https://www.cnblogs.com/ljygoodgoodstudydaydayup/p/5719550.html

【effective c++】资源管理相关推荐

  1. 读书笔记 来自网络

    2010年3月15日 # <深入解析MFC>笔记 12. 进程与线程 2009-10-7 ======================= <深入解析MFC>笔记 12. 进程与 ...

  2. Effective C++ --3 资源管理

    上一部分 Effective C++ --2 构造/析构/赋值运算 13.以对象管理资源 (1)为了防止new后提前return等没有执行delete造成内存泄露,利用RAII(resource ac ...

  3. Effective C# 第二章:.Net资源管理(翻译)

    Chapter 2. .NET Resource Management 第二章:.Net资源管理 一个简单的事实:.Net应用程序是在一个托管的环境里运行的,这个环境和不同的设计器有很大的冲突,这就才 ...

  4. Effective C++ 3nd笔记——资源管理

    Effective C++ 3nd---资源管理 以对象管理资源 简单来说就是要用类来管理资源,最好使用C++11新标准提供的几种智能指针 请记住: 为防止资源泄漏,请使用RAII对象,他们在构造函数 ...

  5. [Effective C++ --014]在资源管理类中小心copying行为

    第一节 <背景> 条款13中讲到"资源取得的时机便是初始化时机"并由此引出"以对象管理资源"的概念.通常情况下使用std中的auto_ptr(智能指 ...

  6. 《Effective C++ 3th》——资源管理

    文章目录 资源如何释放? 注意资源的唯一性 由使用智能指针引出的问题 以对象管理资源 在资源管理类中小心coping行为 在资源管理类中提供对原始资源的访问 成对使用new和delete时要采取相同形 ...

  7. [Effective C++]条款14:在资源管理类中小心copying行为

    复制 RAII 对象必须一并复制它所管理的资源,所以资源的 copying 行为决定 RAII 对象的 copying 行为 普遍而常见的 RAII class copying 行为是:阻止 copy ...

  8. 《Effective C#》读书笔记——条目19:保证0为值类型的有效状态.NET资源管理

    .NET系统的默认初始化过程会将所有的对象设置为0.我们就会难免创建出一个初始化为0值的值类型,所以我们应该将0作为类型的默认值,可以避免一些不必要的Bug. 1.将0设置为枚举的有效值 使用枚举时我 ...

  9. 《Effective C++》第8章 定制new和delete-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  10. Effective C# 原则11:选择foreach循环

    Effective C# 原则11:选择foreach循环 Item 11: Prefer foreach Loops C#的foreach语句是从do,while,或者for循环语句变化而来的,它相 ...

最新文章

  1. Jquery DataTable服务端分页的最佳实现
  2. 安卓项目打开有时候manifests不见了_【必看】暴力0鲁项目详细操作及玩法如何跳过广告,不分享群等...
  3. hadooppythonsql_实例讲解hadoop中的hive查询(python语言实现)
  4. php propel,关于propel--PHP
  5. jQuery使用(四):DOM操作之查找兄弟元素和父级元素
  6. 嵌入式软件架构设计(转载)
  7. 单目标跟踪、多目标跟踪、单目标跟踪发展现状、多目标跟踪发展现状
  8. 大数据分析应用领域有哪些
  9. [项目]PHP图书管理系统(附源码)
  10. 破解水卡最省钱!超详细!--解决小白烦恼
  11. lol8.18服务器不稳定,英雄联盟8.18客户端崩溃,玩家表示要退游,官方会给什么补偿?...
  12. 系统架构设计师论文历年考题(2015-2017)考前冲刺来一波真题
  13. Android Activity向右滑动返回
  14. Linux Mint 18安装sougou拼音输入法
  15. Servlet+JSP项目
  16. 通道注意力机制keras_在TensorFlow+Keras环境下使用RoI池化一步步实现注意力机制
  17. .cxx_destruct crash
  18. 【Python】基于MQTT的聊天客户端
  19. 计算机ntc中国教育考试网,中国教育考试网ntcecf1.neea.edu.cn-2018河北教师资格证成绩查询网址...
  20. 图片传输中的转码问题

热门文章

  1. 【整理】牛客网编程题前端篇(较难难度)
  2. 赛尔笔记 | 通用领域条件性知识图谱数据集
  3. 【ACL2020论文尝鲜】何时采用BERT更加有效?
  4. 【面经】关于Transformer,面试官们都怎么问
  5. 只知道CS224N?斯坦福最新推出NLU公开课CS224U
  6. 【精华版】cw2vec理论及其实现
  7. 每日算法系列【EOJ 3031】二进制倒置
  8. 深度学习2.0-14.神经网络与全连接层之全连接层、输出方式、误差计算
  9. 机器学习基础算法33-HMM实践
  10. 博文视点大讲堂第24期“PPT演示之道”专题讲座成功落幕