C++服务器开发100个知识要点C++RAII惯用法

2023-05-16

  • 最初的写法 
     在笔者刚学习服务器开发的时候,公司给笔者安排了一个练习:在 Windows 系统上写一个 C++程序,用该程序实现一个简单的服务,在客户端连接上来时,给客户端发一条“HelloWorld”消息后关闭连接,不用保证客户端一定能收到。 
     如果熟悉基础网络编程知识,那么你会觉得这很容易,因为这个程序描述的就是TCP网络通信的基本流程,其程序实现流程如下。 
     (1)创建socket。 
     (2)绑定IP地址和端口号。 
     (3)在该 IP 地址和端口号上启动监听,循环等待客户端连接的到来,在客户端连接成功后,向其发送一条“HelloWorld”消息,然后断开连接。 
     在 Windows 上使用网络通信 API 之前,需要使用 WSAStartup 函数初始化socket库;在程序结束时需要使用WSACleanup函数清理socket库。 
     笔者很快就将程序写出来了:

 

 

 

 

 版本2:使用goto语句 
 还是以前面网络通信的代码为例,如果使用goto语句,则该代码可以简化如下:

 

 

 使用 goto 语句后,一旦某个中间步骤出错,则跳转到统一的清理点进行资源清理操作。 
 但是,我们总被告知要慎用goto语句,因为它会让程序的结构变得混乱和难以维护。姑且不论这是否正确,如果不用 goto 语句,那么有没有更好的实现方式呢?有,使用do...while(0)循环。 
 1.1.3 版本3:使用do...while(0)循环 
 以上代码使用do...while(0)循环改进后如下:

 

 

 以上代码利用 do...while(0)循环中的 break 特性巧妙地将资源回收操作集中到一个地方,使用 for 循环也能达到同样的效果。我们同样可以使用 do...while(0)改造上面堆内存分配与释放的示例,伪代码如下:

 

 

 

 这是do...while(0)的一个妙用。但是,在C++中有更好的写法来代替do...while(0),即RAII惯用法。 
 1.1.4 版本4:使用RAII惯用法 
 RAII(Resource Acquisition Is Initialization,资源获取就是初始化)指资源在我们拿到时就已经初始化,一旦不再需要该资源,就可以自动释放该资源。 
 对于 C++来说,资源在构造函数中初始化(可以在构造函数中调用单独的初始化函数),在析构函数中释放或清理。常见的情形就是在函数调用中创建C++对象时分配资源,在 C++对象出了作用域时将其自动清理和释放(不管这个对象是如何出作用域的,不管是否因为某个中间步骤不满足条件而导致提前返回,也不管是否正常走完全部流程后返回)。 
 还是以上面网络通信的例子来说,初始化程序时需要分配两种资源:Windows 的socket网络库和一个用于监听的socket。首先,初始化好Windows socket网络库;然后创建一个用于监听的socket。在程序结束时,我们需要清理这两种资源。 
 使用RAII惯用法改进后的代码如下:

 

 

以上代码并没有在构造函数中分配资源,而是单独使用一个DoInit方法初始化资源,并在析构函数中回收相应的资源。这样在main函数中就不用担心任何中间步骤失败而忘记释放资源了,因为一旦main函数调用结束,serverSocket对象就会自动调用其析构函数回收相应的资源。这就是RAII惯用法的原理! 
 严格来说,以上代码中ServerSocket的成员变量m_bInit应该被设计成类静态成员,调用 WSAStartup 和 WSACleanup 的函数应该被设计成类的静态方法,因为它们只需在程序初始化和退出时各调用一次就可以了。 
 希望读者能理解 RAII 惯用法,因为它在 C++中太常用了。我们也可以使用 RAII 惯用法再次改写上文中分配堆内存的伪代码示例: 

 

 其中,heapObj对象一旦出了其作用域,该程序就会自动调用其析构函数释放堆内存。当然,RAII 惯用法中对资源分配和释放的定义可以延伸出各种外延和内涵,例如对多线程锁的获取和释放。我们在实际开发中也常常遇到以下情形:

 

 这是一段很常见的逻辑:为了避免死锁,我们必须在每个可能退出的分支上都释放锁。随着逻辑写得越来越复杂,我们忘记在某个退出的分支上释放锁的可能性也越来越大。而RAII惯用法正好解决了这个问题:我们可以将锁包裹成一个对象,在构造函数中获取锁,在析构函数中释放锁。伪代码如下:

 使用 RAII 惯用法之后,我们就再也不必在每个函数出口处都加上释放锁的代码了,因为在函数调用结束后会自动释放锁。 
 对于以上代码,有经验的读者可能一眼就看出来了:这不就是C++11中std::lock_guard和 boost 库中 boost::mutex::scoped_lock 的实现原理吗?确实是,本书后续章节会详细介绍操作系统和C++11提供的各类锁的用法。

 1.1.5 小结 
 资源泄露和死锁等问题具有非常强的隐蔽性,如果在生产环境中出现这些问题,则难以复现、排查和定位问题。理解并熟练使用RAII惯用法不仅能让我们的代码更加简洁和模块化,也能让我们在开发阶段避免一部分资源泄漏和死锁问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++服务器开发100个知识要点C++RAII惯用法 的相关文章

  • 交行对账接口100.100.100.X访问超时解决办法

    今天维护一个老的项目 xff0c 一个老的项目已经稳定运行近1年了 最近突然出现故障了 windows服务器 xff0c 中间为了排除问题 xff0c 重启了一下服务器 毕竟windows服务器 xff0c 有时重启包治百病 各种问题都成功
  • 比 MyBatis 快了 100 倍

    比 MyBatis 效率快 100 倍的条件检索引擎 xff0c 天生支持联表 xff0c 使一行代码实现复杂列表检索成为可能 xff01 2开源协议 使用Apache 2 0开源协议 3界面展示 你的产品给你画了以上一张图 xff0c 还
  • python练习100题(5)

    题目054 xff1a 取一个整数a从右端开始的4 7位 切片是左闭右开的 a span class token operator 61 span span class token number 123456789 span a span
  • C语言经典100题——输出“魔方阵“

    lt 1 gt 题目描述 输出 魔方阵 xff0c 所谓魔方阵是指它的每一行 每一列和对角线之和均相等 例如 xff1a 8 1 6 3 5 7 4 9 2 要求输出1 n 2的自然数构成的魔方阵 lt 2 gt 思路分析 将1放在第1行中
  • 编写Python语言,使用循环求解1到100之间数的偶数和

    a 61 1 sum 61 0 while a lt 61 100 if a 2 61 61 0 sum 43 61 a a 43 61 1 print 39 1和100之间的偶数的和为 39 sum
  • toFixed()*100保留的小数位数和预想的不一致

    目录 一 问题 二 原因及解决方法 三 总结 一 问题 1 因为演示需要 xff0c 要造一些假数据 xff0c 一些数据要求保留2位小数 这需求真的不难 xff0c 不就是parseFloat toFixed 不就完了 2 所以很快就写了
  • linux服务器开发里不少是流媒体(音视频)服务器开发

    我发现一个特点 xff0c 不少服务器开发是和音视频流媒体相关的 我发现很多服务器开发是弄音视频服务器开发 见https blog csdn net sinat 16643223 article details 106069991
  • git clone github_提高github下载速度的方法100%有效可达到2MB/s

    点击上方 Python全家桶 xff0c 星标 或 34 置顶 34 关键时刻 xff0c 第一时间送达 作者 kcx64 本文仅做分享 xff0c 若有侵权请联系小编 第一时间删文 阅读本文大概需要 2 8 分钟 因为大家都知道的原因 x
  • 最新的100个微信小程序-极乐Store

    1 团队日历 通过日历管理团队协同任务 在团队内指派 抄送和公开任务事项 xff0c 通过邮件或短信推送消息 到极乐小程序商店中搜索 团队日历 使用 2 同程旅游 同程小程序是一款无需下载安装 xff0c 只需扫描二维码即可 实现产品订购和
  • MessageFilter [target=odom ]: Dropped 100.00% of messages so far.问题解决

    错误提示 WARN 1580994954 426403779 MessageFilter target 61 odom Dropped 100 00 of messages so far Please turn the ros gmappi
  • 100条经典C语言笔试题目

    100 条经典C语言笔试题目 题目来源 xff1a 1 中兴 华为 慧通 英华达 微软亚洲技术中心等中 外企业面试题目 xff1b 2 C 语言面试宝典 林锐 高质量编程第三版 说明 xff1a 1 部分C 语言面试题中可能会参杂部分和C
  • FreeSWITCH 架构

    从来章开始 我们正式开始我们的 FreeSWITCH 之旅 今后我们不再用单独的章节来讲述VoIP中的其它要素和概念 而是在用到时穿插于各个章节之中 总体结构 FreeSWITCH 由一个稳定的核心及外围模块组成 下图来自 FreeSWIT
  • 2021年Linux服务器开发的知识技术合集(基础入门到高级进阶)

    前言 本文介绍下Linux从入门到高级进阶的学习路线 整个路线体系专注于服务器后台开发 知识点包括C C Linux Nginx ZeroMQ MySQL Redis fastdfs MongoDB ZK 流媒体 CDN P2P K8S D
  • C++二叉树遍历总结\100. Same Tree

    理论学习 概念介绍 遍历图解 遍历算法 代码实践 实现模板 Same Tree 题目描述 代码实现 转载请注明出处 http blog csdn net c602273091 article details 55195284 理论学习 概念
  • 为什么 C++ 标准文件流没有更严格地遵循 RAII 约定?

    为什么 C 标准库使用流open close 语义与对象生命周期分离 从技术上讲 关闭销毁可能仍会生成类 RAII 但获取 释放独立性会在范围内留下漏洞 其中句柄可以指向任何内容 但仍需要运行时检查来捕获 为什么库设计者选择他们的方法而不是
  • 术语的含义 - 资源获取就是初始化

    我知道 RAII 是做什么的 这都是为了在代码抛出异常时防止内存泄漏等 现在我想明白这句话的意思smart term http en wikipedia org wiki 收购 http en wikipedia org wiki Acqu
  • 依赖 Windows 句柄的类型作为指针可以吗?

    Windows 句柄有时很烦人 需要记得在之后进行清理 使用创建的笔和画笔执行 GDI 就是一个很好的例子 RAII 解决方案很棒 但是为每种不同类型的手柄制作一个完整的 五规则 RAII 类真的那么好吗 当然不是 我能看到的最好的结果是一
  • 资源获取即初始化 (RAII) 是什么意思?

    资源获取即初始化 RAII 是什么意思 对于一个极其强大的概念来说 这是一个非常糟糕的名字 而且也许是 C 开发人员在转向其他语言时最容易错过的事情之一 有一些运动试图将这个概念重新命名为范围限制的资源管理 尽管它似乎还没有流行起来 当我们
  • 当本机 (C++) 异常传播到 CLR 组件时不会调用析构函数

    我们有大量的本机 C 代码 已编译成 DLL 然后我们有几个包含 C CLI 代理代码的 dll 来包装 C 接口 最重要的是 我们有 C 代码调用 C CLI 包装器 标准的东西 到目前为止 但在很多情况下 本机 C 异常被允许传播到 N
  • 是否有比嵌套“使用”更好的确定性处置模式?

    在 C 中 如果我想确定性地清理非托管资源 我可以使用 using 关键字 但对于多个依赖对象 这最终会嵌套得越来越深 using FileStream fs new FileStream c file txt FileMode Open

随机推荐

  • 手把手教你使用--常用模块--HC05蓝牙模块,无线蓝牙串口透传模块,(实例:手机蓝牙控制STM32单片机点亮LED灯)

    最近在学STM32 xff0c 基本的学完了 xff0c 想学几个模块来巩固一下知识 xff0c 就想到了蓝牙模块 玩啥好难过有很多博客教怎么连的 xff0c 但自己看起来还是有点糊涂 模块的原理和知识点我就不讲解了 xff0c 这里我主要
  • FreeRTOS实时操作系统----机制

    四 机制 目录 四 机制 4 1任务优先级 4 1 1高优先级抢占低优先级 4 1 2时间片 4 2任务调度器 4 3临界段的保护 4 4空闲任务与阻塞延时 4 5任务延时列表 4 6消息队列 4 6 1消息队列的基本概念 4 6 2消息队
  • 三极管导通条件

    NPN三极管 xff0c 箭头朝外 xff1a 高电平导通 PNP三极管 xff0c 箭头朝里 xff1a 低电平导通
  • 74HC1G66模拟开关,多路复用

    SEL为低电平的时候 xff0c SD导通 SEL为高电平的时候 xff0c SD不导通 直接看数据手册
  • 一张图了解MOS管导通条件

    不管他长什么样 xff0c 直接就看箭头指向 箭头向栅极 xff0c 就是nmos管 xff0c 高电平导通 箭头向外 xff0c 就是pmos管 xff0c 低电平导通 一边连了两根线的就是s极
  • Android SDK的安装配置

    SDK xff1a xff08 software development kit xff09 软件开发工具包 被软件开发工程师用于为特定的软件包 软件框架 硬件平台 操作系统等建立应用软件的开发工具的集合 因此 xff0c Android
  • 1.C++简介

    学习目标 xff1a 初识C 43 43 xff0c 介绍C 43 43 一些简单的语法 xff1a 初识C 43 43 数据类型 运算符 程序流程结构 学习内容 xff1a 1 初识C 43 43 一个简单的C 43 43 框架 xff0
  • 死锁形成的原因和四个必要条件

    死锁的概念 死锁是指两个或两个以上的进程 xff08 线程 xff09 在运行过程中因争夺资源而造成的一种僵局 xff0c 若无外力作用 xff0c 这些进程 xff08 线程 xff09 都将无法向前推进 xff0c 这时就形成了死锁 处
  • Android P阻止调用非sdk api后,Atlas该何去何从

    0 背景 自从Android 9 0后 xff0c Android就已经开始着手阻止app开发调用非sdk的api xff0c 也就是被标记为 64 hide的变量 函数 类不可以通过反射调用 xff0c 否则会提示NoSuchMethod
  • 简历应该这么写!

    很多同学刚开始找工作时 xff0c 投出去很多简历 xff0c 但是都石沉大海了 xff0c 没有后文 之所以简历不通过 xff0c 往往都是简历不够 好看 很多大公司HR经常一天要看几百份 xff0c 甚至上千份简历 xff0c 基本都是
  • 希望计算机专业同学都知道这些老师

    C语言教程 翁凯老师 赫斌 翁恺老师是土生土长的浙大码农 xff0c 从本科到博士都毕业于浙大计算机系 xff0c 后来留校教书 xff0c 一教就是20多年 翁恺老师的c语言课程非常好 xff0c 讲解特别有趣 xff0c 很适合初学者学
  • 100个python算法超详细讲解:抓交通肇事犯

    1 xff0e 问题描述 一辆卡车违反交通规则 xff0c 撞人后逃跑 现场有三人目 该事件 xff0c 但都 没有记住车号 xff0c 只记下了车号的一些特征 说 xff1a 牌照的前两位数字是相 同的 xff1b 乙说 xff1a 牌照
  • 100个python算法超详细讲解:百钱百鸡

    1 xff0e 问题描述 中国古代数学家张丘建在他的 算经 中提出了一个著名的 百钱 百鸡问题 xff1a 一只公鸡值五钱 xff0c 一只母鸡值三钱 xff0c 三只小鸡值一钱 xff0c 现 在要用百钱买百鸡 xff0c 请问公鸡 母鸡
  • 100个python算法超详细讲解:水仙花数

    1 xff0e 问题描述 输出所有的 水仙花数 所谓的 水仙花数 是指一个三位数 xff0c 其各位数字的立方 和等于该数本身 xff0c 例如 xff0c 153是 水仙花数 xff0c 因为153 61 1 3 43 1 3 43 3
  • 100个python算法超详细讲解:常胜将军

    100个python算法超详细讲解 64 谷歌学术 1 xff0e 问题描述 有火柴21根 xff0c 两人依次取 xff0c 每次每人只可取走1 xff5e 4根 xff0c 不能多取 xff0c 也不能不取 xff0c 谁取到最后一根火
  • 100个python算法超详细讲解:逆序输出数字

    100个python算法超详细讲解 64 谷哥技术 1 xff0e 问题描述 编程实现将输入的整数逆序输出 2 xff0e 问题分析 前面我们已经接触过很多的递归问题了 xff0c 这些递归问题可以简单 地分成两类 xff1a 一类可以归结
  • 100个python算法超详细讲解:角谷猜想

    1 xff0e 问题描述 角谷猜想在西方常被称为西拉古斯猜想 xff0c 据说这个问题首先是在 美国的西拉古斯大学被研究的 xff0c 而在东方 xff0c 这个问题则由将它带到日 本的日本数学家角谷静夫的名字来命名 xff0c 故被称为角
  • 100个python算法超详细讲解:统计学生成绩

    完整版下载 超详细Python算法案例讲解100例 zip Python文档类资源 CSDN下载 1 xff0e 问题描述 有5个学生 xff0c 每个学生有三门课程的成绩需要统计 要求从键盘输入学生的学号 姓名以及三门课程 的成绩 xff
  • apt update、apt upgrade 和 apt dist-upgrade 的区别

    1 root 64 kali apt update apt update 的作用是从 etc apt sources list文件中定义的源中获取的最新的软件包列表 即运行 apt update 并没有更新软件 xff0c 而是相当 win
  • C++服务器开发100个知识要点C++RAII惯用法

    最初的写法 在笔者刚学习服务器开发的时候 xff0c 公司给笔者安排了一个练习 xff1a 在 Windows 系统上写一个 C 43 43 程序 xff0c 用该程序实现一个简单的服务 xff0c 在客户端连接上来时 xff0c 给客户端