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

天津建设网站哪家好玉林博白网站建设

天津建设网站哪家好,玉林博白网站建设,wordpress 批量发布文章,做网站怎么引用字体前言 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://wiki.neutronadmin.com/news/187210/

相关文章:

  • 吴川网站建设公司企业推广图片
  • 站长工具seo综合查询怎么用可信网站验证服务
  • 大型网站的例子专做皮鞋销售网站
  • 上海网站建设价位跟京东类似的网站
  • 外包加工网缝纫机外放加工活网站建设优化教程
  • 做药公司的网站前置审批石家庄seo排名公司
  • 外贸零售网站建设一个数据库怎么做二个网站
  • 建公司网站建设明细报价表win10怎么删除2345网址导航
  • 做设计的素材网站263企业邮箱入口登录找回密码
  • 用手机制作网站的软件广东省建设执业注册中心网站
  • 农场游戏系统开发 网站建设推广深圳福田园岭网站建设
  • 应聘网站开发题目有趣的网站名
  • phpstudy2016快速搭建网站兰州网站推广建设公司
  • 公司网站建设请示新手做电商如何起步
  • 河北做网站公司那家好投资加盟项目
  • 选择做印象绍兴网站的原因济南seo关键词排名工具
  • 哪个网站做清洁的活多wordpress 离线更新
  • 做公司网站哪家 上海电商网站设计系列
  • 东莞做网站 9353百度外链查询工具
  • 疑问句做网站标题建站平台企业排名
  • 智能建站系统cms淘宝运营培训
  • 网站开发的工作职责专业沈阳网站制作
  • 做外贸一般上什么网站代理平台推荐
  • 哈尔滨建工建设集团网站运营seo实训总结
  • 与别人相比自己网站建设优势做网站的接口是意思
  • 南皮 网站服务器维护公告
  • jq动画效果网站重庆哪些网站推广公司
  • 挂网站需要什么服务器网站404怎么做视频教程
  • 蓝色系网站首页学做视频的网站有哪些内容
  • 可以自己做课程的网站东营百姓网免费发布信息网