C++ IMPL 模式解析(上)
文章目录
- 抛砖引玉
- C++ IMPL 模式
- 完全隐藏成员变量
抛砖引玉
试想一个问题,如果有一套收发数据的网络接口,需要提供给其他同事或厂家使用,包含头文件和动态库,假设头文件如下:
// 版本1
class NetworkV1 {
public:int Send(const std::string str);int Recv(std::string &str);
private:int sockfd;char buf[1024];
};
用户直接 include 头文件,链接库文件即可。方法上没有问题,但问题是头文件中暴露的信息太多了,比如 private 成员变量,而且如果以后的版本中需要增加或删除某些变量,还需要通知用户修改头文件,太麻烦了。
为了解决这个问题,实现接口与实现分离,所以引入了 IMPL 模式。
C++ IMPL 模式
这里的 IMPL 其实就是 implement,即实现的意思,个人觉得 IMPL 严格上来讲,并不算一个设计模式,只是一个更好的 隐藏实现的方法 。已 C++ 为例,它不仅仅是将类的声明和实现放在不同的文件中,更重要的是隐藏细节,只暴露用户必须的接口部分。先看一版改进的代码:
// network.h
// 版本2
class NetworkV2 {
public:int Send(const std::string str);int Recv(std::string &str);private:struct Impl;std::shared_ptr<Impl> impl;
};// network.cpp
// 版本2
struct NetworkV2::Impl {int sockfd;char buf[1024];
};int NetworkV2::Send(const std::string str) {// TODO ...// send(impl->sockfd, str.c_str(), str.size(), 0);return str.size();
}
int NetworkV2::Recv(std::string &str) {// TODO ...// recv(impl->sockfd, impl->buf, 1024, 0);return str.size();
}
这样就做到了隐藏类中的成员变量了,核心思想就是 将成员变量打包放在一个结构体中 ,无论以后的版本中有无删减成员变量,都不会对头文件造成任何影响,这是目前 C++ IMPL 中非常常见的一种调用方法。类似于 C 语言中的 void* 指针,可以在需要的时候转换成任意对象。
完全隐藏成员变量
但是上一种模式还是会有 private 的成员变量,如果是想要完全隐藏,只保留接口呢?我在学习上交所 CTP 接口的时候,还看见过一种新的方法,核心思想是 使用虚函数和继承 。这种模式头文件中只保留接口,不会有任何的成员变量,代码如下:
// network.h
// 版本3
class NetworkV3 {
public:virtual int Send(const std::string str) = 0;virtual int Recv(std::string &str) = 0;// 创建和销毁函数static NetworkV3* New();static void Delete(NetworkV3 *net);
};// network.cpp
// 版本3
class NetworkV3Impl final : public NetworkV3 {
public:int Send(const std::string str) override {std::cout << "NetworkV3Impl::Send: " << str << std::endl;return str.size();}int Recv(std::string &str) {str = "ok";std::cout << "NetworkV3Impl::Recv: " << str << std::endl;return str.size();}
};// 创建和销毁函数
NetworkV3* NetworkV3::New() {return (new NetworkV3Impl());
}
void NetworkV3::Delete(NetworkV3 *net) {delete (NetworkV3Impl*)net;
}
虽然消除了 private 成员变量,但增加了两个静态成员函数 New
和 Delete
,用于创建和销毁对象,也不需要用户自己管理内存,使用上很方便,像 CTP 的 C++ 接口就是采用的这种模式。但后来查资料,发现这种方法有两个主要的弊端:
- 虚函数开销 :虚函数需要使用虚函数表指针间接调用,运行时才能确定调用哪一个函数,无法在编译期间内联优化。在上一版中,在编译期就能确定调用哪一个函数,根本用不到虚函数的特性。
- 二进制兼容 :虚函数是按照索引查询虚函数表来调用的,新增或调整虚函数顺序会造成索引变化,导致新接口在二进制层面不能兼容老接口,就是在末尾增加虚函数,也会有风险。
C++ IMPL 模式解析(上)相关推荐
- C++ IMPL 模式解析(下)
文章目录 二进制兼容 什么是二进制兼容 为什么会二进制不兼容 什么情况会导致二进制不兼容 隐藏子类--解决二进制兼容 参考资料 二进制兼容 在 上一章 的结尾处提到了二进制兼容的概念,这里先说说二进制 ...
- [设计模式] IMPL 模式
说明: 模块型代码中经常可以看到有一些类叫做 class Aimpl , 同时还会存在一个叫 class A的类,从名称上看 Aimpl 是 A 的 implement . 实际上,A 往往是当前模 ...
- Android MVP模式 解析JSON 显示到ListView上
Android MVP模式 解析JSON 显示到ListView上 有关MVP模式的介绍,这里不作详细解释,稍后会更新MVP设计模式,请等待链接-- 简述本次的主要功能实现: 通过mvp设计模式,(M ...
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 从脚本到主类
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [一] 可以去看原文.这里是补充专栏.请看原文 2. 前言 主要针对yarn-per-job模式进行代码分析. ...
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 TaskMasger 启动
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [四] 上一篇: [flink]Flink 1.12.2 源码浅析 : yarn-per-job模式解析 Jo ...
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 JobMasger启动 YarnJobClusterEntrypoint
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [三] 上一章:[flink]Flink 1.12.2 源码浅析 : yarn-per-job模式解析 yar ...
- 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 yarn 提交过程解析
1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [二] 请大家看原文去. 接上文Flink 1.12.2 源码分析 : yarn-per-job模式浅析 [一 ...
- 跨境电商独立站模式解析与机会分析?
随着以Shopify为代表的快速建站工具的兴起,独立站的入门门槛大大降低.因此2019年可能会是独立站一个新的爆发之年.那么国内跨境电商独立站是如何发展演变的,到底有哪些模式?对于希望转型做独立站的平 ...
- 4种常见分支模式解析及优劣对比 | 研发效能提升36计
摘要:4 种常见分支模式解析及优劣对比.团队研发的本质并不是团队规模越大,研发的效率就越高.我们以为团队规模越大,研发效率就会越高,可以做越多的东西,但是我们发现团队规模大到一定程度,整个研发效率是会 ...
最新文章
- Redis高可用之集群配置(六)
- 选中文字改变默认颜色
- 微擎css使用php变量,$_Wamp;全局变量
- 海量服务 | 论服务器极致化海量运营交付的未来
- 亲历2013年TED大会:全球最潮灵感大会
- 计算机应用基础课程基本要求,计算机应用基础课程标准
- mac 安装 tunnelblick
- 让你页面速度飞起来的前端性能优化方案
- 从零开始,跟我一起做jblog项目(一)引言
- 2017-2018论文更新
- 视频开头独白怎么做?一分钟学会
- Python小项目(学生成绩管理系统)7.排序、显示部分
- 手把手系列-从零开始手把手教你前后分离网站
- 微信小程序api视频课程-基础-wx.canIUse的使用
- 独自美丽-西西里的美丽传说『by berta』
- Dreamweaver CS6实战手册
- 游戏代理平台一天结一次靠谱吗?
- dubbo服务暴露原理解析
- BIM+GIS可视化工程管理平台,施工全过程动态监管!
- 博图程序需要手动同步_西门子S7-200SMART PLC 常见问题
热门文章
- matlab实现感知器分类 高斯分布,模式作业设计
- VScode下安装Live Server(自动刷新html页面)
- 幽灵行动断点量子计算机30秒,游戏新消息:幽灵行动断点BETA公测时间公布中字版真人宣传片...
- 与擎标同行 | etsme个人私有云获ISO27001 ISO27701隐国际双认证
- R语言:蒙特卡洛方法求积分
- 求html表格置顶代码,HTML的表格布局
- 蚂蚁区块链李杰力:开放联盟链2020年支持数字积分
- 苹果手机变卡了怎么解决_手机用久了变卡怎么办?关闭这4个开关,跟新手机一样顺畅,学学...
- Chrome 的书签太多如何分类整理比较好
- 复合句 - 定语从句