大型项目开发: 隔离 (《大规模C++程序设计》书摘)

简介: 书中第六章 隔离。 主要在撰述什么需要定义在头文件?什么应当移到编译单元中? 核心仍然是先区分接口定义与实现细节。

书中第六章 隔离。 主要在撰述什么需要定义在头文件?什么应当移到编译单元中?
核心仍然是先区分接口定义与实现细节。实现细节的改变会导致客户代码的重新编译,从逻辑上也表示与客户代码间可能存在着强耦合。

实现细节与隔离

主要考察以下实现细节,它们会在接口中引入实现细节,也是需要考虑进行隔离的内容:

  1. 继承
  2. 分层
    简单的说就是类的成员中有另一个类的实例时,如Foo mFoo. 这个类就会依赖于Foo的定义。而转为持有地址时,即将关系从HasA改为HoldA时,就不存在这个问题。也就是定义为Foo* mFoo;或Foo& mFoo; 这也是Google C++ Coding Style曾经就减少头文件依赖建议过的方式,后来则去掉了这项建议,改为:”不要为了使用前置声明,将成员变量改为指针类型”, 因为它反而增加了逻辑上的复杂度,比如额外的判空处理。
  3. 内联函数
  4. 私有成员
  5. 保护成员
  6. 编译器生成的默认实现函数,如拷贝。
  7. 包含指令,即头文件的包含。
  8. 默认参数
  9. 枚举
    在一些大型项目中,一些存有基本枚举类型的头文件,最后变成没人敢改,而更愿意新增头文件。其实还不如放到具体的域或类中定义。

后面作者对各个细节推荐一些手法,相对比较简单。后面则介绍了几个常用手法:

  1. 协议类(接口类)
  2. Opaque Pointer和PIMPL
  3. Wrapper (封装器), 即引入中间层。

过程接口

考虑到上层代码对底层的操作需求,作者提出了过程接口(The Procedural Interface),可以结合常见的API来理解,它是一组函数的集合,出现在组件的顶部,并将功能的一个子集暴露给用户。作者概括了编程接口的要求:

  1. 接口必须提供必要的功能来操纵底层系统。
  2. 接口一定不能暴露专属的实现细节。
  3. 底层组织的变化必须与客户端程序相隔离。
  4. 与该接口相关的开销一定不能过大。

在实现方式上,以面向对象的Wrapper来实现这样的需求最佳的,而过程接口将针对无法简单使用独立的封装类来实现的系统。其实一个大型系统也是可以拆分出不同的领域,分别以Wrapper的形式来实现的。可以对比WebView的接口,以及Blink中的web层次。
书中主要是探讨了针对所持有对象的操作。上面也提到的Opaque Pointer,还特别说明了Handle(句柄)模式来管理动态分配的对象。

一个过程接口既不是面向对象的也不是特别美观,但它确有一个很大的优点:过程接口总是能够用于将大系统的组织与客户端程序相隔离–即使在设计的早期阶段并没有考虑这样的接口。

隔离或不隔离

隔离会引入一些开销,选择是否进行隔离的常见原因包括:

  1. 暴露 (被使用的范围,或者扇入)
  2. 访问数据的性能
  3. 创建对象的性能
  4. 开发成本 (在没有明确理由的情况强行隔离,会引入额外的开发工作)
  5. 组件的数量 (可能会新增组件,增加维护成本)
  6. 组件的复杂性 (引入新的复杂度,导致难以理解和维护)

作者提供两套经验值供决策时参考(中文编译的图表不太严谨,第5章有图标错,这里明明是两个表,却合成了一个表。)。

访问的相对开销

  1. 内联函数传递值 : 1
  2. 内联函数传递指针 : 2
  3. 非内联函数,非虚函数 : 10
  4. 虚函数机制 : 20

创建相对于单独分配的成本

  1. 自动 (栈上) : 1.5
  2. 动态 (堆上) : 100+

作者最后讨论隔离决策时,建议是否进行隔离取于被使用的范围,性能要求的高低,以及成员函数的大小(是否轻量级)。性能要求高不要隔离,轻量级的实现也不需要隔离。其实就是隔离本身会引入开销,如果为了隔离引入的开销过式,或者引入更不稳定的复杂度,就不要急于隔离。而对于大型、广泛使用的对象则要尽早隔离。

目录
相关文章
|
4月前
|
机器学习/深度学习 算法 算法框架/工具
为什么使用C++进行机器学习开发
C++作为一种高性能语言,在某些性能要求极高或资源受限的场景下也具有非常重要的地位。C++的高效性和对底层硬件的控制能力,使其在大规模机器学习系统中发挥重要作用,尤其是当需要处理大数据或实时响应的系统时。
62 3
|
7天前
|
IDE 开发工具 C语言
C++一分钟之-嵌入式编程与裸机开发
通过这些内容的详细介绍和实例解析,希望能帮助您深入理解C++在嵌入式编程与裸机开发中的应用,提高开发效率和代码质量。
28 13
WK
|
2月前
|
机器学习/深度学习 人工智能 算法
那C++适合开发哪些项目
C++ 是一种功能强大、应用广泛的编程语言,适合开发多种类型的项目。它在游戏开发、操作系统、嵌入式系统、科学计算、金融、图形图像处理、数据库管理、网络通信、人工智能、虚拟现实、航空航天等领域都有广泛应用。C++ 以其高性能、内存管理和跨平台兼容性等优势,成为众多开发者的选择。
WK
112 1
|
3月前
|
Rust 资源调度 安全
为什么使用 Rust over C++ 进行 IoT 解决方案开发
为什么使用 Rust over C++ 进行 IoT 解决方案开发
110 7
WK
|
2月前
|
开发框架 移动开发 Java
C++和Java哪个更适合开发移动应用
本文对比了C++和Java在移动应用开发中的优劣,从市场需求、学习难度、开发效率、跨平台性和应用领域等方面进行了详细分析。Java在Android开发中占据优势,而C++则适合对性能要求较高的场景。选择应根据具体需求和个人偏好综合考虑。
WK
71 0
WK
|
2月前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
123 0
|
3月前
|
NoSQL API Redis
如何使用 C++ 开发 Redis 模块
如何使用 C++ 开发 Redis 模块
|
4月前
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
|
4月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
179 1
|
5月前
|
C++
C++ Qt开发:QUdpSocket网络通信组件
QUdpSocket是Qt网络编程中一个非常有用的组件,它提供了在UDP协议下进行数据发送和接收的能力。通过简单的方法和信号,可以轻松实现基于UDP的网络通信。不过,需要注意的是,UDP协议本身不保证数据的可靠传输,因此在使用QUdpSocket时,可能需要在应用层实现一些机制来保证数据的完整性和顺序,或者选择在适用的场景下使用UDP协议。
230 2
下一篇
开通oss服务