如何在与低(er)级接互时编写良好的C++
How to write good C++ when interacting with low(er) level interfaces?
在我的C++代码中,我必须处理用C编写的接口以及CUDA内核。我在Stackoverflow上发布了一些问题,如何在C++中做这个或那个。我得到了很多答案,比如:"不要那样做。C++有更好的解决方案,看看这个或那个。另一方面,我认为由于与 C 接口或 CUDA 的交互,我真的必须以这种方式做到这一点。
长话短说:我越来越意识到C接口和低级的东西在以良好的C++理念设计代码时会导致困难。
我现在想要什么?我正在寻找一些像"有效C++"这样的文献,但专门针对那些必须处理低层次方面的人。
在构建和设计代码时,您需要牢记一些概念:
- 封装/数据隐藏
- 变革的传播
- 细节/抽象
- 耦合/依赖
常见的体系结构是使用金字塔布局进行抽象。 最底层知道硬件的细节。 向上的每一层都是从硬件到应用程序的抽象。
封装和数据隐藏
这里的想法是,与单个硬件项目相关的每个事物都应该在其封装中。 共享相同功能的常见设备,只是它们位于不同的地址,应从单个接口继承。
例如,给定地址 0x1000、0x2000 和 0x3000 的 3 个 USB 端口,它们都具有相同的方式。 唯一的区别是它们的硬件寄存器位于不同的地址。 因此,应该有一个USB_Interface_Base_Class,以及 3 个实例或 3 个子类。
USB 类应仅公开基本功能。 类的用户不关心硬件寄存器,只关心执行 I/O。 因此,详细信息对类的外部用户是隐藏的。
变革的传播
在研发过程中,硬件是易失性的,可能会发生变化。 在生产过程中也可能会发生变化。 目标是减少变化的传播。 例如,如果将 USB 接口更改为无线,则硬件访问层应更改,但更改不应深入传播到应用程序中。 需要更改的模块越少越好。
细节与抽象
远离硬件的每一层都应该处于比前一层更低的抽象级别。
例如,最高抽象执行:"cout <<"Hello";下一层可能会缓冲数据并调用"驱动程序"。
驱动程序说它想要与字符输出设备通信。默认字符设备连接到 USB。
USB 驱动程序与硬件接口通信以设置寄存器并传输数据。
在最高级别,用户希望将文本输出到默认输出端口,即抽象。 下面的图层填写详细信息以完成工作。
耦合/依赖
两个或模块之间的依赖关系是耦合的。 从紧到松有一定程度的耦合。 当对一个模块的内部更改需要更改为另一个模块时,两个模块被视为紧密耦合。 当对一个模块的内部更改不会影响另一个模块时,两个模块是松散耦合的。
松耦合的目标是帮助减少更改在整个系统中的传播。 如果一个模块访问另一个模块的数据成员,并且数据成员发生更改,则调用模块需要更改。 如果调用模块使用接口,则提供程序可以更改其数据成员,而不会对调用模块产生任何影响。 变革的传播已经停止。
总结
访问硬件不仅仅是编码。 应首先考虑封装、变化传播、抽象和耦合的原则。 访问硬件的代码应遵循这些原则。 一个好的过程是在编码之前牢记原则进行架构和设计。