在软件工程领域,有一个这样的说法,一个项目的注释要占到整个项目代码量的20%。主要因为代码主要是给人维护的,为了易维护,在函数功能、难以理解的程序段以及注意事项都有必要增加注释说明。下面就本人的理解提供C/C++主要的注释模板供参考。
文件注释
以下是文件顶部注释模板,主要内部包括版权说明、文件名、该文件中的主要功能、版本号、文件创建者、时间等内容。实际注释中不包括(1)(2)编号说明。
/***************************************************************
* Copyright(C) 2018,Company All Rights Reserved (1)版权说明
*
* @file : CSqlManager.cpp (2) 文件名
*
* @brief : sql数据库管理类 (3) 该文件主要功能简介
*
* @version : 1.0 (4) 版本信息
*
* @author : Jimmy (5) 创建作者
*
* @date : 2018/12/28 星期五
*
* Details :
***************************************************************/
函数注释
在项目中函数注释是最常见的一种注释,主要包括函数作用、函数参数说明、返回值、时间和作者信息。其函数注释模板如下:
/**************************************************************
* @brief : CADOManager::InitADOConn
*
* @param :
*
* -const STRU_CONN_SQL_INFO& stSqlInfo
*
* -unsigned int timeout
*
* @return : BOOL
*
* @author : Jimmy
*
* @date : 2018/12/22 星期六
*
* @note :
***************************************************************/
结构体注释
对结构体成员右边进行函数说明,为了美观最好注释对齐,模板如下:
typedef struct
{
std::wstring strHost; /*主机地址*/
std::wstring strPort; /*数据库端口*/
std::wstring strUserName; /*用户名*/
std::wstring strPassword; /*密码*/
std::wstring strDBName; /*待校验的数据库*/
}STRU_CONN_SQL_INFO;
变量注释
一般而言,主要是全局变量或者特殊变量才会进行注释,否则通过变量合理命名的形式进行自注释,模板格式如下:
//数据库名字
std::wstring strDBName;
有了以上规则后,就可以在vs2008进行实际配置了
vs2008配置
打开宏管理器
步骤:工具->宏->宏管理器
宏定义
在弹出的宏管理器进行模块命名和宏实现,如下图所示:
需要注意的是Module名要和代码中的module名字一样
宏文件内容格式如下:
Public Module MyAutoCommemt//这里要与保存的Module文件名保持一致,不然无法调用宏'
...
内容实现
...
End Module
其中AddComment是添加注释,FileDescription是文件头注释,FunctionRemark是函数注释。
快捷配置
完成宏实现后,可以通过将光标放在适当位置,点击注释函数名,即可完成注释添加。
为了方便,我们还可以配置快捷键的方式来添加注释,这里以添加文件注释为例进行说明,配置步骤如下:
- 环境->键盘->输入宏函数名
- 选择文本编辑器
- 自定义快捷键
- 分配
- 确定
在需要添加注释的地方按快捷键“ctrl+alt+f”即可生成如下的注释
/***************************************************************
* Copyright(C) 2018,Company All Rights Reserved
*
* @file : NetWorkUtil.cpp
*
* @brief :
*
* @version : 1.0
*
* @author : Jimmy
*
* @date : 2018/12/22 星期六
*
* Details :
***************************************************************/
经过以上配置后,若vs2008宏不能生效则需要在vsmsvr.exe.config 文件中添加<AllowDComReflection enabled="1"/>
内容。
添加方式:
- 搜索 文件 vsmsvr.exe.config
- 在runtime节点下增加
<AllowDComReflection enabled="1"/>
该文件默认位置:
C:\Program Files\Common Files\microsoft shared\VSA\9.0\VsaEnv
或者
C:\Program Files (x86)\Common Files\Microsoft Shared\VSA\9.0\VsaEnv)
源码
以下是完成的宏注释源码:
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Public Module MyAutoCommemt '这里要与保存的Module文件名保持一致,不然无法调用宏'
' --------------------------------------------------
' 生成文件说明注释
' --------------------------------------------------
Sub FileDescription()
Dim gAuthor As String = "Jimmy"
Dim gCompany As String = "Company"
Dim outTextDoc As TextDocument
Dim outText As EditPoint
DTE.ActiveDocument.Selection.GotoLine(1)
outTextDoc = DTE.ActiveDocument.Object("TextDocument")
outText = outTextDoc.StartPoint.CreateEditPoint()
outText.Insert("/***************************************************************" + vbCrLf)
outText.Insert(" * Copyright(C) " + Date.Today.Year.ToString() + "," + gCompany + " All Rights Reserved" + vbCrLf)
outText.Insert(" * " + vbCrLf)
outText.Insert(" * @file : " + DTE.ActiveDocument.Name + vbCrLf)
outText.Insert(" * " + vbCrLf)
outText.Insert(" * @brief : " + vbCrLf)
outText.Insert(" * " + vbCrLf)
outText.Insert(" * @version : 1.0" + vbCrLf)
outText.Insert(" * " + vbCrLf)
outText.Insert(" * @author : " + gAuthor + vbCrLf)
outText.Insert(" * " + vbCrLf)
outText.Insert(" * @date : " + Date.Today + vbCrLf)
outText.Insert(" * " + vbCrLf)
outText.Insert(" * Details :" + vbCrLf)
outText.Insert(" ***************************************************************/" + vbCrLf)
DTE.ActiveDocument.Selection.GotoLine(10)
End Sub
' --------------------------------------------------
'
' 函数注释解析部分
'
' --------------------------------------------------
Public Structure ITEMDATA
Public itemType As Integer
Public itemText As String
End Structure
Public lItemList As New System.Collections.Generic.List(Of ITEMDATA)(4)
Private Function ParseFunctionDescription(ByVal funText As String) As Boolean
Dim strItem As String
Dim idata As ITEMDATA
Dim strSplit As String() = funText.Split("(")
If strSplit.Length = 1 Then
Return False
End If
'解析函数名称部分
If strSplit.Length > 2 Then
strItem = strSplit(strSplit.Length - 2).Trim()
Else
strItem = strSplit(0).Trim()
End If
Dim strHeadSplit As String() = strItem.Split(" ")
strItem = strHeadSplit(strHeadSplit.Length - 1).Trim()
idata.itemType = 1
idata.itemText = strItem.Trim()
lItemList.Add(idata)
'解析参数部分
strItem = strSplit(strSplit.Length - 1).Trim()
If strItem.Substring(0, 1) <> ")" Then
Dim iend As Integer = strItem.IndexOf(")", 0)
Dim strParams As String = strItem.Substring(0, iend).Trim()
Dim strParamSplit As String() = strParams.Split(",")
For Each strItem In strParamSplit
idata.itemType = 2
idata.itemText = strItem.Trim()
lItemList.Add(idata)
Next strItem
Else
idata.itemType = 2
idata.itemText = "none"
lItemList.Add(idata)
End If
'解析返回值类型
Dim iIndex As Integer
For iIndex = 0 To strHeadSplit.Length - 2
idata.itemType = 3
idata.itemText = strHeadSplit(iIndex).Trim()
lItemList.Add(idata)
Next iIndex
Return True
End Function
Sub AddComment()
Dim DocSel As EnvDTE.TextSelection
DocSel = DTE.ActiveDocument.Selection
DocSel.EndOfLine()
ActiveDocument.Selection.Text = " /* */"
End Sub
' --------------------------------------------------
'
' 根据函数声明生成注释
'
' --------------------------------------------------
Sub FunctionRemark()
Dim preSpaceCount As Integer = 0 ' 注释前面的空格数, 缩进(单位:字符)
Dim outTextDoc As TextDocument
Dim outText As EditPoint
Dim iCurrentLineNumber As Integer
Dim iLineLength As Integer
Dim strFunText As String
Dim iItemIndex As Integer
Dim idata As ITEMDATA
lItemList.Clear()
iCurrentLineNumber = DTE.ActiveDocument.Selection.CurrentLine.ToString()
outTextDoc = DTE.ActiveDocument.Object("TextDocument")
outText = outTextDoc.StartPoint.CreateEditPoint()
' 移动文本输入点到指定行上
outText.MoveToLineAndOffset(iCurrentLineNumber, 1)
iLineLength = outText.LineLength
strFunText = outText.GetText(iLineLength)
iLineLength = strFunText.Trim().Length
'但前行没有内容直接返回
If iLineLength = 0 Then
Return
End If
' 解析函数名称
Dim bResult As Boolean = ParseFunctionDescription(strFunText.Trim())
If bResult = False Then
lItemList.Clear()
Return
End If
Dim pcount As Integer = 0
Dim rcount As Integer = 0
Dim strSpace As String = ""
Dim iSpaceIndex As Integer
For iSpaceIndex = 1 To preSpaceCount
strSpace = strSpace + " "
Next
outText.Insert(strSpace + "/**************************************************************" + vbCrLf)
For iItemIndex = 0 To lItemList.Count - 1
idata = lItemList.Item(iItemIndex)
Select Case idata.itemType
Case 1
outText.Insert(strSpace + "* @brief : " + idata.itemText + vbCrLf)
outText.Insert(strSpace + "* " + vbCrLf)
Case 2
If idata.itemText = "none" Then
outText.Insert(strSpace + "* @param : -none" + vbCrLf)
outText.Insert(strSpace + "* " + vbCrLf)
Else
If pcount = 0 Then
outText.Insert(strSpace + "* @param : " + vbCrLf)
outText.Insert(strSpace + "* " + vbCrLf)
End If
pcount = pcount + 1
outText.Insert(strSpace + "* -" + idata.itemText + vbCrLf)
outText.Insert(strSpace + "* " + vbCrLf)
End If
Case 3
If rcount = 0 Then
outText.Insert(strSpace + "* @return : " + idata.itemText + vbCrLf)
outText.Insert(strSpace + "* " + vbCrLf)
End If
rcount = rcount + 1
Case 4
Case 5
End Select
Next
outText.Insert(strSpace + "* @author : " + "Jimmy" + vbCrLf)
outText.Insert(strSpace + "* " + vbCrLf)
outText.Insert(strSpace + "* @date : " + Date.Today + vbCrLf)
outText.Insert(strSpace + "* " + vbCrLf)
outText.Insert(strSpace + "* @note : " + vbCrLf)
outText.Insert(strSpace + "***************************************************************/" + vbCrLf)
lItemList.Clear() '清楚所有元素
End Sub
End Module