分析一套源代码的代码规范和风格并讨论如何改进优化代码

一、目录分析

  拿到一套源代码,首先别急着看源码,第一步要做的应该是分析目录,举个例子:

这套源代码的总目录下分为5个子目录,总目录下除了含有一个顶层CmakeLists.txt文件外。其中还包括:

  •   cmake_modules/目录保存的是一些cmake文件,
  •   config/目录下存放一个配置文件,
  •   include/目录又包含一个子目录myslam/,该子目录存放应用程序相关的头文件,而include/下也可以存放一些库的头文件。
  •   src/目录下主要存放cpp的源文件。
  •   该程序在编译运行前,需要在总目录下新建一个目录build/,然后在build/里make,编译生成的中间文件会全部存放到build/中,避免污染源代码。

二、命名风格

  根据上图所示的cpp原文件名,可以看到文件名直白易懂,基本上概括了该文件所实现的任务。如frontend.cpp应该是实现了视觉里程计前端的功能,而backend.cpp就是实现了后端优化功能,camera.cpp文件是相机相关功能,viewer.cpp应该是主要负责可视化部分。可以看到,不同文件分别负责并实现了一部分功能,具有相似属性的部分尽可能放到同一个文件中,使得源代码层次分明,便于阅读。

  

 1 #ifndef MYSLAM_BACKEND_H
 2 #define MYSLAM_BACKEND_H
 3 
 4 #include "myslam/common_include.h"
 5 #include "myslam/frame.h"
 6 #include "myslam/map.h"
 7 
 8 namespace myslam {
 9 class Map;
10 
11 /**
12  * 后端
13  * 有单独优化线程,在Map更新时启动优化
14  * Map更新由前端触发
15  */ 
16 class Backend {
17    public:
18     EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
19     typedef std::shared_ptr<Backend> Ptr;
20 
21     /// 构造函数中启动优化线程并挂起
22     Backend();
23 
24     // 设置左右目的相机,用于获得内外参
25     void SetCameras(Camera::Ptr left, Camera::Ptr right) {
26         cam_left_ = left;
27         cam_right_ = right;
28     }
29 
30     /// 设置地图
31     void SetMap(std::shared_ptr<Map> map) { map_ = map; }
32 
33     /// 触发地图更新,启动优化
34     void UpdateMap();
35 
36     /// 关闭后端线程
37     void Stop();
38 
39    private:
40     /// 后端线程
41     void BackendLoop();
42 
43     /// 对给定关键帧和路标点进行优化
44     void Optimize(Map::KeyframesType& keyframes, Map::LandmarksType& landmarks);
45 
46     std::shared_ptr<Map> map_;
47     std::thread backend_thread_;
48     std::mutex data_mutex_;
49 
50     std::condition_variable map_update_;
51     std::atomic<bool> backend_running_;
52 
53     Camera::Ptr cam_left_ = nullptr, cam_right_ = nullptr;
54 };
55 
56 }  // namespace myslam
57 
58 #endif  // MYSLAM_BACKEND_H

  这是节选自其中一个头文件的源代码,既然是头文件,c/c++中一般习惯在开头和结尾加上#ifndef、#define和#endif。然后include头文件时,如果是自己写的头文件,就需要写成#include “xxxx.h”的形式,如果要include一个标准库的头文件,就要写成#include <xxxx>的形式。然后在c++中,定义自己的命名空间是非常重要的,为了避免多人合作开发时出现命名冲突。声明命名空间时,其范围内的代码不需要缩进,为了便于阅读。

  作者在命名函数名时,统一采用单词首字母大写的格式,而命名变量时采用全小写,不同单词间用下划线隔开,结尾都加上一个下划线。这样就可以明显的区分函数和变量,无论时采用什么样的命名格式,函数和变量各自统一最重要。

  在声明变量时,变量类型有时候会很长而且复杂,为了避免每次声明变量时都要写一遍较复杂的变量类型,可以使用类型重定义typedef,如typedef std::shared_ptr<Backend>  Ptr,将一个较复杂的类型重定义为较简单明了的名称,这样有助于提高编码效率和源码清晰,也有助于阅读源码。

posted @ 2019-10-12 16:35  Tsungcheng  阅读(176)  评论(0编辑  收藏  举报