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


    一、目录分析

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

    这套源代码的总目录下分为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,将一个较复杂的类型重定义为较简单明了的名称,这样有助于提高编码效率和源码清晰,也有助于阅读源码。

  • 相关阅读:
    Extjs4单选按钮
    下拉框comboxBox本地数据源示例
    处理您的请求时发生异常。此外,对第一个异常执行自定义错误页时发生另一异常。已终止请
    hoj1568
    hoj3434
    poj2924
    poj2909
    hoj3433
    理解Python闭包,这应该是最好的例子
    Spring 学习笔记
  • 原文地址:https://www.cnblogs.com/wzzgeorge/p/11662413.html
Copyright © 2020-2023  润新知