IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 3、资源管理 -> 正文阅读

[C++知识库]3、资源管理

条款13:以对象管理资源

获得资源后立刻放进资源管理对象内 (Resource Acquisition Is Initialization RAII)
管理对象运用析构函数确保资源被释放

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

两个常被使用的RAII class分别是tr1::shared_ptr和auto_ptr。前者通常是较佳选择,因为其copy行为比较直观。若选择auto_ptr,赋值动作会使它指向null

文中的auto_ptr已被C++11所摒弃,考虑用unique_ptr代替

条款14:在资源管理类中小心copying行为

class Lock{
public:
	explicit Lock(Mutex* pm):mutexPtr(pm){
		lock(mutexPtr);	
	}
	~Lock(){unlock(mutexPtr);}
private:
	Mutex* mutexPtr;
}

这样虽然可以保证客户在使用Lock时符合RAII,但是当发生复制时就会有问题

Lock m1(&m);
Lock m2(m1);

所以此时应该采用一定的方式去保证复制时不出问题:
1、禁止复制
2、对底层资源使用引用计数法
3、复制底部资源,即深拷贝
4、转移底部资源

复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为
普遍而常见的RAII class copying行为是:抑制copying、施行引用计数法

条款15:在资源管理类中提供对原始资源的访问

std::tr1::shared_ptr<Investment> pInv(createInvestment());
int daysHeld(const Investment* pi);

这种情况下,使用资源管理类造成API无法调用。
所以资源管理类应该提供对原始资源的访问。
1、显式转换

class Investment{
public:
	InvestmentHandle* get() const{return mInvest;}
}

通过get函数返回原始资源
2、隐式转换

class Investment{
public:
	operator InvestmentHandle*() const{return mInvest;}
}

通过重载operator()提供隐式转换来返回原始资源。

APIs往往要求访问原始资源,所以每一个RAII class应该提供一个取得原始资源的办法
对原始资源的访问可能经由显式转换或隐式转换。一般而言显式转换更安全,但隐式转换更方便

条款16:成对使用new和delete时要采取相同形式

用new[]申请内存的话就要用delete[]去释放。用new申请内存的话就用delete去释放

条款17:以独立语句将newed对象置入智能指针

int priority();
void processWidget(std::tr1::shared_ptr<Widget> pw, int priority)

调用时如果采用这种方式:

processWidget(new Widget, priority());

编译不通过,因为tr1::shared_ptr的构造函数是explicit,不允许隐式转换。
可以改为下面的方式

processWidget(std::tr1::shared_ptr<Widget>(new Widget), priority());

但是此方式有可能会出现问题:
因为编译器对 priority()、new Widget和tr1::shared_ptr构造函数三个的执行顺序不一定,有可能出现先执行new Widget 再执行priority()最后执行tr1::shared_ptr构造函数。这时如果priority()出现异常,那个new Widget返回的指针就变成了野指针。

所以要这么写

std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());

以独立语句将newed对象置入智能指针内。如果不这样做,一旦抛出异常,有可能会造成内存泄漏。

虽然本章内容大部分已被C++11解决,但是本章的思想还是值得学习的。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 22:56:44  更:2021-07-14 22:58:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 10:23:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码