当前位置: 首页 > news >正文

网站建设 软件开发的公司福建省建设厅网站施工员查询

网站建设 软件开发的公司,福建省建设厅网站施工员查询,大屯街道网站建设,1空间做2个网站吗前言 RAII的含义是“资源获取即初始化”。 一段看似安全的代码 首先看一段代码#xff1a; try{int *p new int[100];// ... do somethingdelete[] p; }catch(exception e){ // ..... } 这段代码中#xff0c;我们先进行了动态内存分配#xff0c;使… 前言 RAII的含义是“资源获取即初始化”。 一段看似安全的代码 首先看一段代码 try{int *p new int[100];// ... do somethingdelete[] p; }catch(exception e){ // ..... } 这段代码中我们先进行了动态内存分配使用完释放看起来很完美但是这段程序是否真的保证不会发生内存泄漏 考虑这样一种情形程序在使用这段内存的过程中throw一个异常于是程序转向catch块然后XXX。 这段内存被释放了吗 显然没有。 那么这段程序应该从哪里改进呢 对象的生命期 考虑一个问题C中对象的声明期是怎样的在C中对象创建的方式有两种一种是栈上一种是堆上创建。 { Animal a; // stack Animal *pa new Animal(); // heap } 上面的代码中第一个对象创建在栈上更明确的说法是它是一个局部变量这意味着它的生命期起源于被创建的这行语句终结与所在作用域的末尾也就是这里的右花括号}。 而第二个对象呢它是采用所谓的动态内存分配生成的需要程序员手工去释放当调用delete的时候才销毁但调用delete的时机不是固定的。 也就是说栈对象的生命期是明确的而堆对象的生命期由于取决于调用delete的时机因而是不明确的。 看到这里之前那段有可能内存泄漏的代码如何去改进呢 答案就是用栈对象明确的生命期去管理资源。 用对象的生命期管理资源 试想一下如果我们把之前程序中对内存的分配写在构造函数中把释放资源写在析构函数中而栈对象的生命期是明确的当该管理资源的对象过期时连同它管理的资源一起释放岂不是非常智能化 我们尝试着写出下列代码 class ScopePtr{ public: ScopePtr(int *p):_p(p){} ~ScopePtr(){ delete[] _p; } private: int *_p; }; 我们把之前的代码做如下的改进 try{ScopePtr scope(new int[100]);// ... do something}catch(exception e){ // ..... } 再来分析一下这段代码 如果正常执行那么当执行完try块时scope对象过期执行析构函数同时释放了那段数组。如果使用的过程中发生了异常那么当程序进入catch块时同样会销毁try内的局部变量。 无论是哪种情况内存总是会被释放。 如果这里不是int而是其他复杂的类型使用这个封装的ScopePtr是不是不太方便显然不会我们去重载成员操作符就可以了使它表现的像个指针这就是一个最简单的智能指针的产生。 问题得到了完美的解决 资源获取即初始化 我们上面解决问题的办法就是RAII技术RAII的含义是“资源获取即初始化”这个概念有两个要点 获得资源后立即放进管理对象管理对象运用析构函数确保资源被释放 看另外一个例子我们在访问一些临界区资源的时候通常需要加锁所以产生了下面的代码 { mutex.lock(); //do sth..mutex.unlock(); } 这种方式是很容易出现问题的例如程序中间遇见错误情况需要退出这个函数此时很容易忘记解锁 { mutex.lock(); //do sth.. if(...){ return false // forgot to unlock }// ... mutex.unlock(); } 此时如果再次进行Lock操作就造成了死锁。 解决这个问题的办法仍然很简单我们去写一个类 class MutexLockGuard{public: MutexLockGuard(MutexLock mutex):_mutex(mutex){ _mutex.lock(); } ~MutexLockGuard(){ _mutex.unlock(); }private: MutexLock _mutex;}; 这样刚才那段代码就可以修改成 { MutexLockGuard guard(lock); //do sth.. if(...){ return false }// ... } 这样一旦离开这段代码程序立刻自动解锁。 不过为了防止错误使用这个类例如 MutexLockGuard(lock); 可以定义一个宏 #define MutexLockGuard(m) ERR MutexLockGuard 这样我们在错误使用的时候编译期间就能发现错误。 一种泛型解决方案 刘未鹏在他的《C11及现代C风格和快速迭代式开发》中提出了一种泛型实现利用了C11的function和Lambda匿名函数如下 class ScopeGuard{public: explicit ScopeGuard(std::functionvoid() onExitScope) : onExitScope_(onExitScope), dismissed_(false) { }~ScopeGuard() { if(!dismissed_) { onExitScope_(); } }void Dismiss() { dismissed_ true; } private: std::functionvoid() onExitScope_; bool dismissed_; private: // noncopyable ScopeGuard(ScopeGuard const); ScopeGuard operator(ScopeGuard const);}; 使用方式也很简单 HANDLE h CreateFile(...);ScopeGuard onExit([] { CloseHandle(h); }); 其实就是将该资源释放的函数代码段注册到Scope类其中原理不再赘述。 与其他语言的对比 RAII是C独有的编程手段。通过RAII技术我们能够做到资源不需要使用时立即释放这是其他GC语言所不具备的。 以Java为例Java具有完善的GCGarbage Collection垃圾回收机制但是存在如下的缺点 GC只能回收内存而对于打开的文件、数据库连接等仍然需要手工关闭。GC因为进程优先级等原因回收效率底下详情可以参考孟岩的《垃圾收集机制(Garbage Collection)批判》 conclusion RAII技术是现代C编程技术中及其重要的一部分甚至有人称其为“C编程中最重要的编程技法”可见其重要性。通过RAII我们完全可以实现资源的自动化管理写出永不内存泄漏的程序。 参考资料 《C Primer》《Effective C》《Linux多线程服务器端编程》
http://www.zqtcl.cn/news/956502/

相关文章:

  • 如何建设一个视频网站西安个人做网站
  • wordpress站群教程市场营销培训课程
  • 17网站一起做网店白沟简单网页制作图片
  • 网站建设项目需求分析流程做商业地产的网站
  • 百度建站商业网点的定义
  • 古镇建设网站经济研究院网站建设方案
  • 会员网站开发百度自己的宣传广告
  • 重庆网络推广网站推广自己设计图纸的软件
  • 国内免费的短视频素材网站什么网站做博客好
  • 个体户网站建设wordpress修改作者链接
  • 做企业网站怎么样如何做网站的登录注册
  • 网站建设中标怎么做网站文字图片
  • 济南网站推广徽hyhyk1公司展示网站模板
  • ae免费模板下载网站视频网站数据库设计
  • 找做金融的网站网站建设方面存在的问题
  • 门户网站建设与开发wordpress添加文章总数标签总数
  • 想创办一个本地的人才招聘网站_如何做市场调查问卷windows7优化大师下载
  • 做网站建设要什么证视频付费网站建设
  • html网站建设实例代码软件下载app排行榜
  • 高端个人网站网站建设密码
  • 全网seo秦皇岛市做网站优化
  • 简述站点推广有哪些方式大兴做网站公司
  • 网站关键词密度查询太仓网站设计早晨设计
  • 厦门市同安区建设局官方网站永嘉网站建设
  • 工程师网站建设网页设计与制作基础教程答案
  • php 开发手机网站建设互动平台抽手机
  • 网站 被降权网页平面设计要学什么
  • 团购网站短信平台中国建设银行网站客户注册码
  • 编辑网站的软件手机软件wordpress幻灯片源码
  • 网站开发比较厉害推荐一本学做网站的书