Skip to content
李健 edited this page Jun 14, 2023 · 5 revisions

C++ 代码规范

本文档列出了在公司内使用C++语言进行的设计和编码标准。

@TOC

[[TOC]]

##一般规则

  • 在所有文件中包含版权标题
  • 尽量避免全局变量
  • 在使用前检查指针
  • 检查范围(例如数组)以避免索引不足或越界
  • 避免除零错误
  • 变量和方法尽可能使用const
  • 使用成对的new和delete避免内存泄漏
  • 使用智能指针时注意循环引用, 数据持有者应持有智能指针, 数据使用者可使用弱指针或裸指针
  • 使用多线程时要小心。在客户端开发时我们的首选的方式是UI和主消息循环是单线程的;多线程应用于于后台工作(例如,网络数据传输,图像分析/分割等...)
  • 尽量在单独的行上声明每个变量
  • 避免使用c语言式的强制类型转换,使用c++ cast操作符
  • 在switch语句中注意每个case语句的返回和中断或应使用return和break
  • 在switch语句或注释中包含default处理
  • 尽量避免使用goto语句
  • 在函数声明中, 输入参数应在输出参数之前列出
  • 输入参数的值尽量使用值或const引用
  • 输出参数的值首选引用指针
  • 一个函数应执行最小化的单个功能,并且方法命名可以反映该函数功能
  • 优先使用常量变量而不是#define来提高类型安全性
  • 出现在界面上的文字内容优先使用qt translate框架(tr), 根据项目情况考虑可能的多语言的支持(请参阅QApplication :: translate)

##格式化

  • 使用K&R风格
  • 函数和代码块的的左括号显示在下一行
  • 大括号内的语句缩进
  • 函数的右括号显示在下一行上
  • 结束括号应与起始括号保持同一缩进
  • 单个行尽量不要超过120个字符
  • 使用4个空格的制表符缩进
  • 在关键字后面使用单个空格
  • 不要在左括号后或右括号前包括空格
  • 在与方法名同行上声明方法返回类型

##错误处理

  • 如果所使用的类库会抛出exception, 则应使用try..catch捕获异常进行处理,否则程序应使用返回值来判断方法执行结果
  • 除非需要状态码处理, 否则一般情况下需要返回处理结果的一般函数应使用bool值返回结果

##命名

  • 头文件命名为.h扩展名, 代码文件命名为.cpp扩展名, 如扩展和继承其它框架(如VTK, ITK), 则扩展名可以和对应框架一致, 同时命名风格也可以参照框架
  • 避免使用短名称(单个字符名称在目的明显的地方是可以的,例如i,j,k用于计数)
  • 避免无意义的命名
  • 避免使用缩写。如果使用缩写,则在方法,变量和参数定义中一致地使用它。
  • 避免使用缩写。如果使用缩写,则在方法,变量和参数定义中一致地使用它。
  • 使用驼峰命名法(如saveFileAsXML, printEmployeePaychecks)
  • 对于方法名称,请使用小写开头驼峰命名(如setFileName, executeCalculation)
  • 对于类,结构体,枚举和文件名使用大写开头的驼峰大小写, 类名和文件名保持一直(如FileUtility和FileUtility.cpp)
  • 类成员变量以下划线开头,然后使用小写开头驼峰命名, 如_hasComplete
  • 使用get或set开始访问器方法(例如getCenterPoint(),setCenterPoint())
  • 对bool返回值的函数使用问题命名(例如isValid())
  • 使用由下划线分隔的大写字符用于命名常量和宏定义(例如MAX_STRING_LENGTH)

##注释和文档

  • 对关键逻辑应该提供注释正确描述代码行为
  • 类和public函数应进行文档注释, 除非类或函数名称已经足够清晰说明该类和函数的作用, 对于需要解释的参数, 同样应增加注释,
  • 文档注释采用doxygen格式
  • 常用的类注释标记包括@ class,@ author和@brief
  • 常用的函数注释标注包括@param和@return
  • 使用@see交叉引用其他类,函数,文件等。

##类定义规范

  • 在格式为类name_h的头文件中包含#define guard
#ifndef CenterPoint_h
#define CenterPoint_h
...
#endif
  • 或者使用#pragma once也可以避免循环应用
  • 尽量使用前置声明而不是include对应头文件
  • 使用virtual析构函数
  • 定义默认构造函数,而不是依赖于编译器自动生成的版本
  • 如带有一个参数的构造函数有多个, 建议使用c++关键字explicit,以避免意外转换
  • 继承的虚函数尽量使用override关键字
  • 避免构造函数中执行可能失败的代码或调用虚函数
  • 避免在析构函数中执行可能失败或可能引发异常的代码
  • 声明成员变量为非public,并在必要时提供访问方法
  • 类方法声明应按public, protected, private进行排序
  • 类成员变量应声明在方法之后

##现代c++

  • 在C++11标准之后, C++已经增加多种新增功能. 在可能的情况下, 使用新提供的特性来提高效率以及避免传统C++的各种隐患.
  • 使用智能指针, auto类型推到和 lambda 函数时,可以更快地编写代码、加强代码并更好地了解代码。 for_each 比 for循环更整洁和易于使用,并且不容易发生意外错误。 可以使用样本和最少行数的代码来编写应用。

如:

// C-style
for (int i = 0; i < v.size(); ++i)
{
	std::cout << v[i];
}

// Modern C++:
for (auto& num : v)
{
	std::cout << num;
}

##代码文件版权信息范例

//*************************************************************************
// UEG Medical
// http://www.ueg.com.cn/
// Copyright 2020 UEG. All rights reserved.
//
// Filename: AnnotationForm.h
//
//*************************************************************************

##文档注释范例 ####类文档

/**
 * @class AnnotationForm
 * @brief.
 *
 * 
 *
 * @author
 */

####函数文档

/**
 * Mask
 */
int MaskController::getNumOfMask() const {
    return num;
}

##日志记录 todo

##常用工具 AStyle可以用来简化代码缩进和统一代码格式 AStyle有一个visual studio插件, 可以通过扩展商店进行安装

安装完成后, 在VS的设置选项里找到Astyle: image.png 点击AStyle Formatter,选择C/C++tab: 点击Edit,拷贝“--style=kr --indent=spaces=4 --indent-switches --pad-oper --pad-header --unpad-paren --mode=c”,保存。 点击Settings,的选项应该如下: ![image.png](/.attachments/image-c88cb41a-ea28-4b4b-843c-a2a43c319430.png =700x)

Clone this wiki locally