C++资源管理操作方法详解

目录
  • 以对象管理资源
  • 在资源管理类中小心copy行为
  • 在资源管理类中提供对原始资源的访问
  • 成对使用new和delete时要采用相同形式
  • 以独立语句将new对象置入智能指针

以对象管理资源

class A{...};
//工厂函数createA来提供特定的A对象
A* createA();
//坏情况
void f(){
    A* p=createA();
    ...
    delete p;//如何在delete之前程序先return了,则无法delete
}
//为了确保资源释放 将资源放进对象内 利用对象的析构函数来释放
void f(){
    std::shared_ptr<A> p(createA());
    ...
    //程序结束后会经shared_ptr的析构函数释放
}

auto_ptr已经被废除,主要原因是其拷贝会造成所以权转移,所以使用shared_ptr更好

以对象管理资源的关键想法:

1、获得资源后立刻放进管理对象内

2、管理对象运用析构函数释放资源

注意是:shared_ptr和auto_ptr两者都在析构函数上使用delete而不是delete[],所以在动态分配的数组上使用它们不好。当然我觉得还是少用动态数组,用vector,string啥的就能代替咯。

在资源管理类中小心copy行为

复制RAII对象时有两种选择:

1、禁止复制--------将copying操作声明为private

class Lock:private Uncopyable{
public:
    ....
};

2、对底层资源祭出"引用计数法"--------即shared_ptr

class Lock{
public:
    explicit Lock(Mutex* pm):mutexPtr(pm,unlock)//unlock函数为删除器
    {
        lock(mutexPtr.get());
    }
private:
    shared_ptr<Mutex>mutexPtr;
}

复制底部资源:需要资源管理类对象的唯一理由是不需要某个复件资源时确保被释放,在此情况下复制资源管理类对象,应该也复制其所包括的资源,即深拷贝------当一个对象被复制时,不论指针或其所指内存都会被制作出一个复件,即深拷贝。

转移底部资源所有权:auto_ptr,你只希望有一个RAII对象指向一个未加工资源,即使被复制也是如此。

在资源管理类中提供对原始资源的访问

前提:智能指针其实是一个类

shared_ptr<A>p(createA());
//假如有以下函数
int func(const A* pi);
//如下调用错误 因为p是一个智能指针不是一个指向A的指针
int f=func(p);
//调用get函数返回原始资源
int f=func(p.get());

智能指针重载了指针取值操作符(->,*) 允许隐式转换到原始指针

//例如A有一个函数,p是一个指向A的智能指针
int A::getNum();
//如下调用合格,其实是发生了一个智能指针到原始指针的隐式转换
int num=p->getNum();

一般而言显示转换比较安全,隐式转换客户使用方便。

成对使用new和delete时要采用相同形式

delete的最大问题在于:即将被删除的内存之内究竟有多少个对象

即:被删除的那个指针是指的单一对象还是成对数组?

string* p1=new string;
string* p2=new string[100];
delete p1;
delete[] p2;

规则很简单:new中用了[],delete就要用[]

以独立语句将new对象置入智能指针

假设有一个函数来揭示处理程序的优先权,另一个函数用来在动态分配所得的Widget上进行某些带有优先权的处理

int priority();
void processWidget(shared_ptr<Widget>pw,int priority);
//错误
processWideget(new Widget,priority());
//因为shared_ptr的构造函数需要一个原始指针,该构造函数是explicit,无法隐式转换
processWideget(shared_ptr<Widget>(new Widget),priority());//可以

但是编译器执行顺序不确定,调用该函数前,编译器需要:

调用priority,执行new Widget,shared_ptr构造函数

但调用priority的顺序可以是第一第二或第三(new 和智能指针的先后顺序不能变)

如何是先new,后priority,再shared_ptr,万一priority调用失常,则new出来的指针遗失,尚未置入shaerd_ptr的构造函数,则会资源泄漏。

因此分开写最好:

shared_ptr<Widget>pw(new Wideget);
processWidget(pw,priority());

到此这篇关于C++资源管理操作方法详解的文章就介绍到这了,更多相关C++资源管理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++实现简单酒店管理系统

    本文实例为大家分享了C++实现简单酒店管理系统的具体代码,供大家参考,具体内容如下 酒店管理系统设计报告 一. 需求分析 题目要求如下: 某酒店有客房若干间,其中客房分为不同等级,如豪华.标准.普通等,客房床位数也不同.例如,豪华套房有4个床位,400元/晚:标准客房2个床位,200元/晚:普通客房1个床位,100元/晚. 顾客分金卡会员.银卡会员.普通会员及非会员,其享受的折扣不同.例如,金卡会员可享受8折优惠,银卡会员可享受9折优惠,普通会员享受95折优惠,非会员不享受优惠. 当顾客连续入住

  • C++演讲比赛管理系统实现流程实例

    目录 演讲比赛系统 1.需求分析 2.程序和功能 3.程序逻辑 3.1建立演讲比赛管理类 3.2开始演讲比赛程序 3.3查看往届比赛结果程序 3.4清空记录 3.5等待程序和随机产生姓名程序 4.程序下载 演讲比赛系统 1.需求分析 学校举行一场比赛,共有12人参加.比赛共两轮,第一轮为淘汰赛,第二轮为决赛. 每名选手都有对应的编号:如10001~10012. 比赛方式:分组比赛,每组6个人. 第一轮分为两个小组,整体按照选手的编号进行抽签后顺序演讲. 十个评委分别给每名选手打分,去除最高分和最

  • C++实现页面的缓冲区管理器

    目录 1. 实验目标 2. 代码实现 3.实验结果 1. 实验目标 本次实验要实现一个页面的缓冲区管理器. 具体要实现以下的函数: ~BufMgr(): 清除所有脏页并释放缓冲池和 BufDesc 表 void advanceClock(): 用来找到下一个时钟的位置 void allocBuf(FrameId& frame): 使用时钟算法分配自由帧:如有必要,将脏页写回磁盘. void readPage(File* file, const PageId PageNo, Page*& p

  • C++资源管理操作方法详解

    目录 以对象管理资源 在资源管理类中小心copy行为 在资源管理类中提供对原始资源的访问 成对使用new和delete时要采用相同形式 以独立语句将new对象置入智能指针 以对象管理资源 class A{...}; //工厂函数createA来提供特定的A对象 A* createA(); //坏情况 void f(){ A* p=createA(); ... delete p;//如何在delete之前程序先return了,则无法delete } //为了确保资源释放 将资源放进对象内 利用对象

  • jQuery中each()、find()和filter()等节点操作方法详解(推荐)

    1.each(callback) 官方解释: 返回值:jQuery 概述 以每一个匹配的元素作为上下文来执行一个函数. 意味着,每次执行传递进来的函数时,函数中的this关键字都指向一个不同的DOM元素(每次都是一个不同的匹配元素).而且,在每次执行函数时,都会给函数传递一个表示作为执行环境的元素在匹配的元素集合中所处位置的数字值作为参数(从零开始的整型). 返回 'false' 将停止循环 (就像在普通的循环中使用 'break').返回 'true' 跳至下一个循环(就像在普通的循环中使用'

  • Python之str操作方法(详解)

    1. str.format():使用"{}"占位符格式化字符串(占位符中的索引号形式和键值对形式可以混合使用). >>> string = 'python{}, django{}, tornado{}'.format(2.7, 'web', 'tornado') # 有多少个{}占位符就有多少个值与其对应,按照顺序"填"进字符串中 >>> string 'python2.7, djangoweb, tornadotornado'

  • django基础之数据库操作方法(详解)

    Django 自称是"最适合开发有限期的完美WEB框架".本文参考<Django web开发指南>,快速搭建一个blog 出来,在中间涉及诸多知识点,这里不会详细说明,如果你是第一次接触Django ,本文会让你在感性上对Django有个认识,完成本文操作后会让你有兴趣阅读的相关书籍和文档. 本文客操作的环境,如无特别说明,后续都以下面的环境为基础: =================== Windows 7/10 python 3.5 Django 1.10 ======

  • Python之re操作方法(详解)

    一:re.search():search返回的是查找结果的对象,可以使用group()或groups()方法得到匹配成功的字符串. ①group() 默认返回匹配成功的整个字符串(忽略pattern中的括号),也可以指定返回匹配成功的括号中第几个字符串(从1开始计数): ②groups() 以元组的形式返回匹配成功的pattern中括号中的内容,若pattern中没有括号,则返回空元组. 以上这篇Python之re操作方法(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多

  • Python之os操作方法(详解)

    1. os.path.driname(path):返回路径的上一级路径字符串. >>> os.path.dirname('D:\Games') 'D:\\' >>> 2. os.path.basename(path):返回路径的最后一级目录名(文件夹名)或文件名(全称). >>> os.path.basename('D:\Games\9yin_632\蜗牛整包\\0x0804.ini') '0x0804.ini' >>> 3. os.

  • jquery属性,遍历,HTML操作方法详解

    Jquery属性遍历.HTML操作. Jquery拥有可操作HTML元素和属性的强大方法. 下面是我整理的一些jquery遍历函数: .add() 将元素添加到匹配元素的集合中. .andSelf() 把堆栈中之前的元素集添加到当前集合中. .children() 获得匹配元素集合中每个元素的所有子元素. .closest() 从元素本身开始,逐级向上级元素匹配,并返回最先匹配的祖先元素. .contents() 获得匹配元素集合中每个元素的子元素,包括文本和注释节点. .each() 对 jQ

  • PHP 数组基本操作方法详解

    数组的概念 数组(array)是 PHP 中一个非常重要的概念,我们可以把数组看做一系列类似的数据的集合,实际上数组是一个有序图. PHP 还提供了超过 70 个内建函数来操作数组. 创建数组 使用 array() 语言结构创建数组: <?php $arr_age1 = array(18, 20, 25); // 或者: $arr_age2 = array("wang"=>18, "li"=>20, "zhang"=>25

  • Python-OpenCV基本操作方法详解

    基本属性 cv2.imread(文件名,属性) 读入图像 属性:指定图像用哪种方式读取文件 cv2.IMREAD_COLOR:读入彩色图像,默认参数,Opencv 读取彩色图像为BGR模式 !!!注意 cv2.IMREAD_GRAYSCALE:读入灰度图像. cv2.imshow(窗口名,图像文件) 显示图像 可以创建多个窗口 cv2.waitKey() 键盘绑定函数 函数等待特定的几毫秒,看是否由键盘输入. cv2.namedWindow(窗口名,属性) 创建一个窗口 属性:指定窗口大小模式

  • Pandas实现数据拼接的操作方法详解

    目录 merge 操作 merge 拼接方式 merge 举例 join 操作 join 举例 concat 操作 concat 举例 append 举例 数据科学领域日常使用 Python 处理大规模数据集的时候经常需要使用到合并.链接的方式进行数据集的整合,其中应用的数据类型包括 Series 和 DataFrame,可以使用的方法也很多,比如本文中介绍的 .merge(). .join() 和 .concat() 三种方法,进行拼接处理后的数据集可以发挥最大的用途. merge 操作 .m

随机推荐