「编程模型」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
回复
举报
回复
    相关推荐