回复
「编程模型」C++ 代码组织
蓝月亮
发布于 2020-9-2 18:17
浏览
1收藏
场景
注:以 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)」
- 避免定义太多头文件搜索路径,同一模块,甚至同一代码仓库到头文件引用可以使用完整的相对路径
- 在开发前期不要聚合太多头文件到一起,等模块完成功能发布之后,可以考虑引用方便再聚合到一起。
分类
标签
赞
1
收藏 1
回复
相关推荐