文章目录

  • 抛砖引玉
  • 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 成员变量,但增加了两个静态成员函数 NewDelete ,用于创建和销毁对象,也不需要用户自己管理内存,使用上很方便,像 CTP 的 C++ 接口就是采用的这种模式。但后来查资料,发现这种方法有两个主要的弊端:

  • 虚函数开销 :虚函数需要使用虚函数表指针间接调用,运行时才能确定调用哪一个函数,无法在编译期间内联优化。在上一版中,在编译期就能确定调用哪一个函数,根本用不到虚函数的特性。
  • 二进制兼容 :虚函数是按照索引查询虚函数表来调用的,新增或调整虚函数顺序会造成索引变化,导致新接口在二进制层面不能兼容老接口,就是在末尾增加虚函数,也会有风险。

C++ IMPL 模式解析(上)相关推荐

  1. C++ IMPL 模式解析(下)

    文章目录 二进制兼容 什么是二进制兼容 为什么会二进制不兼容 什么情况会导致二进制不兼容 隐藏子类--解决二进制兼容 参考资料 二进制兼容 在 上一章 的结尾处提到了二进制兼容的概念,这里先说说二进制 ...

  2. [设计模式] IMPL 模式

    说明: 模块型代码中经常可以看到有一些类叫做 class Aimpl , 同时还会存在一个叫 class A的类,从名称上看 Aimpl 是 A 的 implement  . 实际上,A 往往是当前模 ...

  3. Android MVP模式 解析JSON 显示到ListView上

    Android MVP模式 解析JSON 显示到ListView上 有关MVP模式的介绍,这里不作详细解释,稍后会更新MVP设计模式,请等待链接-- 简述本次的主要功能实现: 通过mvp设计模式,(M ...

  4. 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 从脚本到主类

    1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [一] 可以去看原文.这里是补充专栏.请看原文 2. 前言 主要针对yarn-per-job模式进行代码分析. ...

  5. 【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 ...

  6. 【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 ...

  7. 【flink】Flink 1.12.2 源码浅析 : yarn-per-job模式解析 yarn 提交过程解析

    1.概述 转载:Flink 1.12.2 源码浅析 : yarn-per-job模式解析 [二] 请大家看原文去. 接上文Flink 1.12.2 源码分析 : yarn-per-job模式浅析 [一 ...

  8. 跨境电商独立站模式解析与机会分析?

    随着以Shopify为代表的快速建站工具的兴起,独立站的入门门槛大大降低.因此2019年可能会是独立站一个新的爆发之年.那么国内跨境电商独立站是如何发展演变的,到底有哪些模式?对于希望转型做独立站的平 ...

  9. 4种常见分支模式解析及优劣对比 | 研发效能提升36计

    摘要:4 种常见分支模式解析及优劣对比.团队研发的本质并不是团队规模越大,研发的效率就越高.我们以为团队规模越大,研发效率就会越高,可以做越多的东西,但是我们发现团队规模大到一定程度,整个研发效率是会 ...

最新文章

  1. Redis高可用之集群配置(六)
  2. 选中文字改变默认颜色
  3. 微擎css使用php变量,$_Wamp;全局变量
  4. 海量服务 | 论服务器极致化海量运营交付的未来
  5. 亲历2013年TED大会:全球最潮灵感大会
  6. 计算机应用基础课程基本要求,计算机应用基础课程标准
  7. mac 安装 tunnelblick
  8. 让你页面速度飞起来的前端性能优化方案
  9. 从零开始,跟我一起做jblog项目(一)引言
  10. 2017-2018论文更新
  11. 视频开头独白怎么做?一分钟学会
  12. Python小项目(学生成绩管理系统)7.排序、显示部分
  13. 手把手系列-从零开始手把手教你前后分离网站
  14. 微信小程序api视频课程-基础-wx.canIUse的使用
  15. 独自美丽-西西里的美丽传说『by berta』
  16. Dreamweaver CS6实战手册
  17. 游戏代理平台一天结一次靠谱吗?
  18. dubbo服务暴露原理解析
  19. BIM+GIS可视化工程管理平台,施工全过程动态监管!
  20. 博图程序需要手动同步_西门子S7-200SMART PLC 常见问题

热门文章

  1. matlab实现感知器分类 高斯分布,模式作业设计
  2. VScode下安装Live Server(自动刷新html页面)
  3. 幽灵行动断点量子计算机30秒,游戏新消息:幽灵行动断点BETA公测时间公布中字版真人宣传片...
  4. 与擎标同行 | etsme个人私有云获ISO27001 ISO27701隐国际双认证
  5. R语言:蒙特卡洛方法求积分
  6. 求html表格置顶代码,HTML的表格布局
  7. 蚂蚁区块链李杰力:开放联盟链2020年支持数字积分
  8. 苹果手机变卡了怎么解决_手机用久了变卡怎么办?关闭这4个开关,跟新手机一样顺畅,学学...
  9. Chrome 的书签太多如何分类整理比较好
  10. 复合句 - 定语从句