「编程模型」C++ 代码组织

发布于: 2020 年 06 月 17 日
「编程模型」C++代码组织

场景

注:以 C++11 版本来展开阐述。

C++11 没有官方的包管理、模块功能,代码组织这块还处于手动管理阶段。代码组织会影响下面几个方面,或者说以下几个方面和代码组织有关:

  • 方便 Makefile / CMakeLists.txt 等编译配置的编写

  • 方便手动定位要找的文件、类、函数等

  • 组织方式符合直观认识

解决方案

目录和文件

考虑到多平台的兼容性,目录和文件均使用小写字母+下划线来命名,即蛇形命名风格。

目录层次和「命名空间 / namespace」相对应,主要靠目录来组织模块,文件辅助之:

  • 命名空间起到了模块的作用,不管模块划分的依据是什么,为每个模块都分配单独的命名空间

  • 建立一个和命名空间层级相同的目录,用来存放实现的 .cpp 代码

  • 头文件分 2 部分,对模块外公开的单独放一个头文件,该头文件和存放实现代码的目录同级

  • 模块内的头文件可以和实现代码放一起

├── modA
│   ├── fun1.cpp
│   ├── fun1.h
│   └── fun2.cpp
├── modA.h
├── modB
│   ├── fun1.cpp
│   ├── fun1.h
│   ├── fun2.cpp
│   └── fun2.h
└── modB.h

命名空间

命名空间最好能直观地反映架构的设计,这样在看了架构设计的文档之后,看代码时能方便地对应起来。

所以命名空间的划分就是架构设计的划分,一般包含下面几个维度:

  • 命名空间由大到小体现了架构范围由粗到细的过程

  • 大的范围,如分层的划分,如果有垂直维度的,也可以和分层在同一级别

  • 小的范围,如单独的业务模块,也可以按技术功能划分模块

namespace app {}
namespace rt {
namespace log {}
namespace config {}
namespace io {}
}
namespace ui {
namespace login {}
namespace home {}
}
namespace model {
namespace user {}
namespace monitor {}
}

编译优化

这里的优化指的是减少编译时间,最主要的就是轻量化各模块的公开头文件,可以简单理解为手动维护的「模块导入」。

反例的典型代表就是在一个头文件里包含所有其他的头文件,美名其曰「一个头文件搞定」。

当然,一个头文件也是可以搞定的,不过这是终极优化后的结果,需要采取如下几个步骤后达到:

  • 头文件中,引用模块外的定义,都使用前置声明

  • 由于只能使用前置声明,所以引用的定义只能是指针形式,这里统一使用「智能指针(std::shared_ptr)」

  • 避免定义太多头文件搜索路径,同一模块,甚至同一代码仓库到头文件引用可以使用完整的相对路径

  • 在开发前期不要聚合太多头文件到一起,等模块完成功能发布之后,可以考虑引用方便再聚合到一起。

发布于: 2020 年 06 月 17 日 阅读数: 25
用户头像

顿晓

关注

因观黑白愕然悟,顿晓三百六十路。 2017.10.17 加入

一个不爱编程的程序员, 一个用软件来解决问题的工程师, 一个有匠心的手艺人。

评论

发布
暂无评论
「编程模型」C++代码组织