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

【C++】早绑定、析构与多态 | 一道关于多态的选择题记录

今天在和群友聊天的时候看到了一道很坑的题目,分享给大家

1.看题!

先来看看题目

struct Dad
{
public:Dad(){ echo();}~Dad(){ echo();}virtual void echo() {cout << "DAD ";}
};struct Son:Dad
{
public:void echo() const override {cout << "SON ";}
};Son ss;

请问这个的输出是什么?

A  "DAD DAD "
B  "DAD SON "
C  "SON DAD "
D  "SON SON "
E  编译出错
F  运行出错

答案是E,编译出错!

2.涉及到的知识点

2.1 知识点

先来说说这道题目里面涉及到了什么知识点

  • 多态调用;
  • 多态重写函数需要满足什么条件;
  • 类内函数后加const的作用;
  • 类内函数后加override的作用;
  • 什么是早绑定和晚绑定

一个一个复习吧!

  • 多态调用是父类指针/引用指向子类时,调用虚函数会调用子类重写后的版本
  • 多态重写函数的条件:函数名/参数/返回值都必须相同(注意还有协变)
  • 类内函数后加const修饰的是这个对象的this指针,被修饰的函数中无法修改类内成员变量
  • 类内函数后加override是让编译器来严格检查是否构成重载
  • 早绑定:静态绑定;晚绑定:动态绑定(具体请看CPP多态的博客)

2.2 分析题目

注意看父类和子类中这两个echo()函数的区别

virtual void echo(){}//父类
void echo() const override {}//子类

首先需要说明的是,子类函数中virtual关键字是可以省略的,但即便省略了,这个函数依旧是个虚函数。

这里子类的函数中多了const修饰,而这个const修饰的就是函数中隐含的this指针,此时子类中echo()函数的参数就发生了变化!

virtual void echo(Son* this) { } // 不加const
virtual void echo(const Son* this) { } // 加const

正是因为这里的this指针出现了const的修饰,所以子类的echo和父类echo的参数类型不同,不构成虚函数重写!再加上override关键字的严格检查,会直接编译报错!

正确的写法是删除子类echo中的const或者给父类echo函数加上const

3.再来看题

好了,坑人的点看完了,再来看个「常规」的,就是把上面的题干改成能编译通过的。此时又应该选谁呢?

struct Dad
{
public:Dad(){ echo();}~Dad(){ echo();}virtual void echo() const{cout << "DAD ";}
};struct Son:Dad
{
public:void echo() const override {cout << "SON ";}
};Son ss;
A  "DAD DAD "
B  "DAD SON "
C  "SON DAD "
D  "SON SON "

image-20230822211806379

编译运行,可以看到,结果是DAD DAD,应该选A

3.1 分析

在给 Son 类定义构造函数和析构函数时,没有指定调用父类的对应构造函数和析构函数。因此,在创建 Son 对象 ss 时,会默认调用 Dad 类的构造函数和析构函数。

由于 Dad 类中的构造函数和析构函数调用了虚函数 echo(),而这个虚函数在子类 Son 中被重写,所以会根据对象类型调用相应的重写函数。然而,在构造函数和析构函数中,虚函数机制不会按照预期工作。

构造函数中调用虚函数时,会忽略动态绑定机制,直接调用父类的函数版本。因此,在 Dad 的构造函数中调用 echo(),实际上调用的是 Dad 类中的 echo() 函数,而不是 Son 类中的重写版本。

同样地,析构函数中也会忽略动态绑定机制,直接调用父类的函数版本。所以,在 Dad 的析构函数中调用 echo(),依然调用的是 Dad 类中的 echo() 函数。

因此,当创建 Son 对象 ss 并打印输出时,会先调用 Dad 类的构造函数并打印 "DAD ",然后调用 Dad 类的析构函数并再次打印 "DAD "

3.2 结论

在父类的构造和析构中,对象的版本都被确定为父类的版本,会采用早绑定来调用父类自己的函数,而不是子类的重写后的函数;

简单记忆:父类的构造和析构中如果出现虚函数,只会调用父类自己的函数!


这是因为编译器需要保证正确的构造和析构顺序,如果父类析构里调用子类的虚函数,可能会出现下面的场景

struct Dad
{
public:Dad(){ echo();}~Dad(){ echo();}virtual void echo() const{cout << "DAD ";}
};struct Son:Dad
{
public:Son() {_a = new int(3);}~Son() {delete _a;}void echo() const override {cout << "SON ";delete _a;}
private:int _a;
};Son ss;

如果父类中的析构echo()调用子类重写的函数,此时就会出现子类已经被销毁(子类的析构函数早于父类析构调用)的_a被二次delete,两次delete同一片空间是会报错的!

所以为了避免这种情况,父类的析构中采用早绑定,子类重写的虚函数不会生效!

这种行为是为了确保在对象的构造和析构过程中,按照正确的顺序调用各个类的构造和析构函数,避免在对象处于未完全初始化或已部分销毁状态时调用子类的函数。

包括父类的构造也可以这么理解,如果父类构造里面可以调用子类的虚函数,可能会出现两次对一个子类对象进行new空间,会产生内存泄露;

但构造函数还和虚函数表的初始化有关系,此时虚函数表还没有完全初始化,子类对象尚未构造完成,没有多态调用的条件,所以也不能调用到子类重写后的虚函数。

相关文章:

【C++】早绑定、析构与多态 | 一道关于多态的选择题记录

今天在和群友聊天的时候看到了一道很坑的题目&#xff0c;分享给大家 1.看题&#xff01; 先来看看题目 struct Dad { public:Dad(){ echo();}~Dad(){ echo();}virtual void echo() {cout << "DAD ";} };struct Son:Dad { public:void echo() const override…...

mac下安装tomcat

1. 官网下载Apache Tomcat - Apache Tomcat 9 Software Downloads 2. 授权bin目录下所有.sh文件权限sudo chmod 755 *.sh 3. 启动程序(后台运行) sudo sh ./startup.sh 4. 在当前窗口启动程序&#xff0c;随时看到日志sudo sh ./catalina.sh run 5. 关闭程序 sudo sh ./shu…...

【小梦C嘎嘎——启航篇】string常用接口的模拟实现

【小梦C嘎嘎——启航篇】string常用接口的模拟实现&#x1f60e; 前言&#x1f64c;string 模拟实现1、iterator 迭代器相关使用函数实现2、构造函数接口实现3、 传统写法——拷贝构造函数接口实现4、 现代写法——拷贝构造函数接口实现5、析构函数接口实现6、传统写法—— 赋…...

【Jenkins】持续集成部署学习

【Jenkins】持续集成部署学习 【一】安装部署【1】Jenkins所处位置【2】Docker安装Gitlab&#xff08;1&#xff09;首先准备一台空的虚拟机服务器&#xff08;2&#xff09;安装服务器所需的依赖&#xff08;3&#xff09;Docker的安装&#xff08;4&#xff09;阿里云镜像加速…...

Redis数据结构之List

Redis 中列表&#xff08;List&#xff09;类型是用来存储多个有序的字符串&#xff0c;列表中的每个字符串成为元素 Eelement&#xff09;&#xff0c;一个列表最多可以存储 2^32-1 个元素。 在 Redis 中&#xff0c;可以对列表两端插入&#xff08;push&#xff09;和弹出&am…...

SpringCloud Alibaba实战和源码(7)Skywalking

什么是SkyWalking Skywalking是由国内开源爱好者吴晟开源并提交到Apache孵化器的产品&#xff0c;它同时吸收了Zipkin /Pinpoint /CAT 的设计思路。特点是&#xff1a;支持多种插件&#xff0c;UI功能较强&#xff0c;支持非侵入式埋点。目前使用厂商最多&#xff0c;版本更新较…...

MySQL索引可能失效之or、is null、is not null、不等于(!=,<>)、联合索引

1、如果 A,B 两列都有索引&#xff0c;那么 select * from Table where Aa or Bb; 会走索引吗&#xff1f; 答案&#xff1a;会&#xff0c;因为 A,B都有索引&#xff1b; 2、如果 A,B有索引&#xff0c;但是C没有索引&#xff1b; select * from Table where Aa or Bb …...

无人机电力巡检:探索电力设施维护的新模式

电力巡检一直是电力行业中关键的环节&#xff0c;它的目的是确保电力设施的正常运行和安全稳定&#xff0c;对提高电力设施的可靠性、确保电力供应的稳定性和提高电力企业的管理水平具有重要的意义。传统的电力巡检方式通常采用人工的方式进行&#xff0c;这种方式存在很多的问…...

ethers.js1:ethers的安装和使用

ethers官方文档&#xff1a;Documentation 1、ethers简介&#xff1a; ethers.js是一个完整而紧凑的开源库&#xff0c;用于与以太坊区块链及其生态系统进行交互。如果你要写Dapp的前端&#xff0c;你就需要用到ethers.js。 与更早出现的web3.js相比&#xff0c;它有以下优点…...

小程序中的页面配置和网络数据请求

页面配置文件和常用的配置项 1.在msg.json中配置window中的颜色和背景色 "navigationBarBackgroundColor": "#efefef","navigationBarTextStyle": "black" 2.可以看到home中的没有发生变化但是msg的发生变化了&#xff0c;这个和前面的…...

使用ImageMagick实现多张图片拼接为gif(多线程版)

官网: https://imagemagick.org/ 直接上代码 ExecutorService es Executors.newFixedThreadPool(10); List<File> images getImageFiles(sceneDir); CountDownLatch cdl new CountDownLatch(images.size()); // 拷贝图片 for (File file : images) {System.out.prin…...

解释 RESTful API,以及如何使用它构建 web 应用程序。

RESTful API是一种利用HTTP协议进行通信的Web API设计风格&#xff0c;它采用了一组统一且可缓存的操作&#xff0c;包括GET、POST、PUT、DELETE等&#xff0c;通过URL来定位资源&#xff0c;以及使用JSON、XML等格式来传输数据&#xff0c;以实现系统之间的数据交互和资源共享…...

远程端口转发 实践 如何将物理机某一端口的服务转发到vps上,使得外网能访问到

以本机1470端口&#xff08;我的sqli-labs&#xff09;与vps的9023端口为例。 SSH基本的连接命令是&#xff1a; ssh usernamehostname这里牵扯到了两台主机&#xff0c;一是执行命令、运行SSH客户端的主机&#xff0c;我们称为本地主机A【Host A】&#xff1b;二是接收连接请…...

【uniapp 监听键盘弹起与收回】

在uniapp中&#xff0c;可以通过使用小程序提供的API来监听键盘弹起与收回。 首先&#xff0c;在页面的onLoad函数中注册监听事件&#xff1a; onLoad() {uni.onKeyboardHeightChange(this.onKeyboardHeightChange); },然后&#xff0c;在页面的onUnload函数中取消注册监听事…...

【Unity】如何制作小地图

我们为什么要制作小地图呢&#xff1f; 原因很简单&#xff1a; 导航和定位&#xff1a;小地图可以显示玩家当前位置以及周围环境的概览。这使得玩家能够更好地导航和定位自己在游戏中的位置&#xff0c;找到目标或避开障碍物。场景了解&#xff1a;通过小地图&#xff0c;玩…...

基于IMX6ULLmini的linux裸机开发系列八:按键处理实验

目录 GIC相关寄存器 GPIO中断相关寄存器 中断服务函数表 中断向量表偏移位置 make有报错 解决方法&#xff1a;error: for loop initial declarations are only allowed in C99 mode_‘for’ loop initial declarations are only allowed i_Young_2717的博客-CSDN博客 GIC…...

数据结构好题总结

Cut Inequality Down 题解 https://blog.csdn.net/lzh_naive/article/details/103340568 概括&#xff1a;st表倍增类st表 考虑如果没有UL限制的话&#xff0c;相当于是前缀和 我们发现&#xff0c;如果某次到了U/L&#xff08;相当于是一次碰壁&#xff09;那么这个值已知…...

Java串口开发

网上搜索了关于java串口开发的资料,发现都不是特别的全,故写下一些心得以帮助其他人能快速上手java串口开发,如有错漏之处&#xff0c;敬请指正 串口开发会用到一个javax.comm和RXTXcomm库,&#xff0c;javax.comm库不支持64位操作系统。该库仅适用于32位操作系统,所以接下来主…...

Python nohup 启动python脚本,后台没有日志

一、情况 1.linux上运行python脚本&#xff0c;前台运行打印日志&#xff0c;后台使用nohup不打印日志。 前台运行 ./xxx.py 后台运行 nohup python ./xxx.py > xxx.log 2>&1 &二、排查思路 2.1 脚本是否有问题 首先看自己写的python脚本是否存在问题。因为…...

完美解决微信小程序使用复选框van-checkbox无法选中

由于小程序使用了vant-ui框架&#xff0c;导致checkbox点击无法选中问题 <van-checkbox value"{{ checked }}" shape"square"><view class"check-content"><view class"checktext">我已阅读并同意>《用户协议》…...

IDEA报错:类文件具有错误的版本 61.0,应为52.0

springboot项目启动报错&#xff1a; 类文件具有错误的版本 61.0,应为52.0 请删除该文件或确保该文件位于正确的类路径子目录中 查阅了网上的很多资料&#xff0c;普遍原因说是springboot版本过高&#xff0c;高于3.0 需要在pom文件中降低版本 也有说是idea的maven配置java版…...

Linux 挂载局域网内共享目录

Linux 挂载局域网内共享目录 1、安装samba服务端2、samba服务端配置3、添加samba服务访问账户4、防火墙5、重启服务6、windows访问7、linux访问 1、安装samba服务端 sudo apt-get install -y samba yum install -y samba2、samba服务端配置 vim /etc/samba/smb.conf在文档尾部…...

FFmpeg解码32k大分辨率出现如下错误:Picture size 32768x32768 is invalid

最近找到一张32k的jpeg图片&#xff0c;尝试用ffmpeg来进行解码&#xff0c;命令如下&#xff1a; ffmpeg -i enflame_32768-32768-420.jpg 32.yuv结果出现Picture size 32768x32768 is invalid的错误&#xff1a; 找到报错的代码文件imgutils.c&#xff0c;以及函数&#x…...

EasyExcel+POI制作带有有效性校验及下拉联动的Excel模板

文章目录 1.背景2.实现功能的Excel特性2.1.特性介绍2.2.下拉框联动2.3.单元格自动匹配Id2.4.错误提示 3.代码实现3.1.基础流程代码3.2.名称管理器配置3.3.有效性配置3.4.函数填充3.5.其他补充 4.总结 1.背景 最近在做一个CRM系统的人员销售目标导入的相关需求&#xff0c;需要…...

Unity怎么制作魔法火焰特效?Unity制作魔法火焰特效方法

Unity制作魔法火焰特效方法&#xff1a; 在第一次玩Supergiant Games的RPG游戏《Hades》时&#xff0c;游戏的美术和视觉效果让人非常吃惊。受此启发&#xff0c;希望能够尝试制作类似风格的作品。 工作流程 整个工作从制作简单的火焰贴图开始。首先&#xff0c;我使用PhotoS…...

双基证券:房地产基本面仍处下行通道 政策有望促进走稳

摘要 【双基证券&#xff1a;房地产基本面仍处下行通道 方针有望促进走稳】双基证券表明&#xff0c;2023年5、6、7月商品房及二手房销量继续走弱&#xff0c;引发商场关注。咱们从各城市环线、住所户型、小区物业费的维度盯梢了房地产出售数据的走势&#xff0c;当前新房出售…...

31、springboot 配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口

配置HTTP服务端口及如何通过WebServer实例动态获取项目中的HTTP端口 ★ 设置HTTP服务端口&#xff1a; - server.port或者SERVER_PORT环境变量——总结来说&#xff0c;其实就是要配置server.port外部配置属性。▲ 同样遵守如下优先级&#xff1a; 这些都是外部配置源&#x…...

会计如何使用ChatGPT提高工作效率

文章目录 ChatGPT改变了会计行业微软重新定义了PC交互应对ChatGPT带来的冲击给财务人员的建议总结 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社…...

【TypeScript】类型推论和类型别名

类型推断 TypeScript 的类型推断是一种编译器能够自动分析代码并确定变量的类型的功能。它允许你在声明变量时省略类型注释&#xff0c;让 TypeScript 根据变量的值来推断出合适的类型。 以下是 TypeScript 类型推断的一些示例和情况&#xff1a; 基本类型推断&#xff1a; …...

字节码调教的入口 —— JVM 的寄生插件 javaagent 那些事

Java Instrumentation 包 Java Instrumentation 概述 Java Instrumentation 这个技术看起来非常神秘&#xff0c;很少有书会详细介绍。但是有很多工具是基于 Instrumentation 来实现的&#xff1a; APM 产品: pinpoint、skywalking、newrelic、听云的 APM 产品等都基于 Instru…...

Blender卡通着色入门

当想到 Blender 和 3D 设计时&#xff0c;你的想法可能会转向风格化渲染或照片级渲染和 VFX。 但是&#xff0c;你是否知道 Blender 还可以创建可与 2D 动漫风格和漫画书类似的图形&#xff1f; 推荐&#xff1a;用 [NSDT编辑器 快速搭建可编程3D场景 1、什么是卡通着色&#x…...

性能调优篇 一、Jvm监控及诊断工具-命令行篇

目录 一、概述1、简单命令行工具 二、jps&#xff1a;查看正在运行的Java程序1、是什么&#xff1f;2、测试3、基本语法 三、jstat&#xff1a;查看jvm统计信息 一、概述 性能诊断是软件工程师 1、简单命令行工具 二、jps&#xff1a;查看正在运行的Java程序 1、是什么&…...

Docker部署MongoDB 5.0.5

1、查看目录 rootwielun:~# tree mongo mongo ├── conf │ └── mongod.conf ├── data ├── docker-compose.yml └── logrootwielun:~# cd mongo rootwielun:~/mongo# chmod 777 log2、配置docker-compose.yml rootwielun:~/mongo# cat docker-compose.yml ve…...

Day18-2-地狱回调-Promise-async-await技术

文章目录 Promise技术一 回调函数二 异步任务三 回调地狱是什么?四 如何解决回调地狱1 PromisePromise基本用法使用Promise解决地狱回调2 async/awaitPromise技术 一 回调函数 当一个函数作为参数传入另一个函数中,并且它不会立即执行,只有当满足一定条件后该函数才可以执…...

echarts范围限制下性能问题

最近实习遇到一个问题&#xff0c;需要对折线图的数据进行范围限制&#xff0c;比如将超过100的设置为100&#xff0c;低于0的设置为0&#xff1b; 原来的代码是创建一个数组&#xff0c;然后遍历原数组&#xff0c;超过的push100&#xff0c;低于0的push0&#xff0c;在中间的…...

wazuh环境配置以及案例复现

目录 wazuh环境配置wazuh案例复现 wazuh环境配置 一、wazuh配置 1.1进入官网下载OVA启动软件 Virtual Machine (OVA) - Installation alternatives (wazuh.com) 1.2点击启动部署&#xff0c;傻瓜式操作 1.3通过账号&#xff1a;wazuh-user&#xff0c;密码&#xff1a;wazuh进…...

解决el-select回显异常 显示option选项的value 而不是显示label

1、问题 回显的value和选项value类型不同 form中v-model"form.userId"是字符串类型 option中:value“item.userId” 选项id是数字类型 2、办法 :value“item.userId” 改为 :value“item.iduserId‘’”&#xff08;转换成字符串&#xff09; <el-form-item l…...

【【STM32-SPI通信协议】】

STM32-SPI通信协议 STM32-SPI通信协议 •SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司开发的一种通用数据总线 •四根通信线&#xff1a;SCK&#xff08;Serial Clock&#xff09;、MOSI&#xff08;Master Output Slave Input&#xff09;、MISO…...

板卡常用前端 数据表操作

两年前写的&#xff0c;现在看,有点想吐, 数据操作表,调试设备用 采用外挂的方法&#xff0c;以前设备的接口命令,简易&#xff0c;换个UI展示很容易 自己写着玩的,公司部分产品再用,前端展示,不涉密 index.html <!doctype html> <html><head><meta chars…...

基于AVR128单片机世界电子时钟的设计

一、系统方案 上电初始化完成系统初始化&#xff0c;液晶滚动显示北京、莫斯科、东京、伦敦、巴黎、纽约等六个城市的标准时间&#xff0c;显示的内容包括地区名及相应地区的年、月、日、星期、时、分、秒。 使用K1按键控制滚动显示或稳定显示某个地区的时间。 使用K3、K4、K5按…...

Electron学习2 使用Electron-vue和Vuetify UI库

Electron学习2 使用Electron-vue和Vuetify UI库 一、Electron-vue简介二、安装yarn三、创建Electron-vue项目1. 关于 electron-builder2. 安装脚手架3. 运行4. 打包应用程序 四、background.js说明1. 引入模块和依赖&#xff1a;2. 注册协议&#xff1a;3. 创建窗口函数&#x…...

Java“牵手”根据商品分类ID获取速卖通商品分类详情页面数据获取方法,速卖通API实现批量商品数据抓取示例

速卖通商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取速卖通商品分类详情和商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问速卖通商城的网页来获取商品分类详情信息。以下…...

QT 使用图表

目录 1、概念 1.1 坐标轴-QAbstractAxis 1.2 系列-QAbstractSeries 1.3 图例-Legend 1.4 图表-QChart 1.5 视图-QChartView 2、 QT 折线图 2.1 Qt 折线图介绍 2.2 Qt 折线图实现 Qt 图表是专门用来数据可视化的控件 Qt 图表包含折线、饼图、棒图、散点图、范围图等。…...

SSRF 服务器端请求伪造

文章目录 SSRF(curl)网址访问通过file协议访问本地文件dict协议扫描内网主机开放端口 SSRF(file_get_content)网站访问http协议请求内网资源通过file协议访问本地文件 SSRF(Server-Side Request Forgery:服务器端请求伪造) 其形成的原因大都是由于服务端提供了从其他服务器应用…...

shell 05(shell索引数组变量)

一、数组 shell 支持数组 (Array)&#xff0c;数组是若干数据的集合&#xff0c;其中的每一份数据都称为数组的元素. 注意Bash shell 只支持一维数组&#xff0c;不支持多维数组。 在 Shell 中&#xff0c;用括号( )来表示数组&#xff0c;数组元素之间用空格来分隔. 语法为&…...

爬虫异常处理:异常捕获与容错机制设计

作为一名专业的爬虫程序员&#xff0c;每天使用爬虫IP面对各种异常情况是我们每天都会遇到的事情。 在爬取数据的过程中&#xff0c;我们经常会遇到网络错误、页面结构变化、被反爬虫机制拦截等问题。在这篇文章中&#xff0c;我将和大家分享一些关于如何处理爬虫异常情况的经…...

Python自动化小技巧21——实现PDF转word功能(程序制作)

案例背景 为什么这个年代PDF转word&#xff0c;某wps居然还要收费.....很多软件都可以实现这个功能&#xff0c;但是效果都有好有坏&#xff0c;而且有的还付费&#xff0c;很麻烦。 那就用python实现这个功能吧&#xff0c;然后把代码打包为.exe的程序&#xff0c;这样随便在…...

Vue使用Element的表格Table显示树形数据,多选框全选无法选中全部节点

使用Element的组件Table表格&#xff0c;当使用树形数据再配合上多选框&#xff0c;如下&#xff1a; 会出现一种问题&#xff0c;点击左上方全选&#xff0c;只能够选中一级树节点&#xff0c;子节点无法被选中&#xff0c;如图所示&#xff1a; 想要实现点击全选就选中所有的…...

SpringBoot生成和解析二维码完整工具类分享(提供Gitee源码)

前言&#xff1a;在日常的开发工作当中可能需要实现一个二维码小功能&#xff0c;我参考了网上很多关于SpringBoot生成二维码的教程&#xff0c;最终还是自己封装了一套完整生成二维码的工具类&#xff0c;可以支持基础的黑白二维码、带颜色的二维码、带Logo的二维码、带颜色和…...

Redis的基本知识(偏八股)

前言 本文篇概念&#xff0c;着重介绍Redis的执行效率、功能作用、数据类型、 执行效率 江湖上都流传这Redis的执行效率是挺快的&#xff0c;那为什么说它快呢&#xff1f;有以下几个原因&#xff1a; 基于内存单线程模型高效数据结构非阻塞I/O 基于内存: 内存的读写效率是…...