您的位置:首页 > 编程语言 > C语言/C++

doxygen 使用简介(C,C++为代码作注释)

2009-03-11 20:19 549 查看
原文:/article/6007656.html

doxygen注释块

doxygen注释块其实就是在C"C++注释块的基础添加一些额外标识,使doxygen把它识别出来,并将它组织到生成的文档中去。
在每个代码项中都可以有两类描述,这两类描述将在文档中格式化在一起:一种就是brief描述,另一种就是detailed。两种都是可选的,但不能同时没有。
顾名思义,简述(brief)就是在一行内简述地描述。而详细描述(detaileddescription)则提供更长,更详细的文档。
在doxygen中,有多种方法将注释块标识成详细描述:
1.你可以使用JavaDoc风格,即在C风格注释块开始使用两个星号'*',就像这样:

2./**

3.*...描述...

4.*/


5.或者你使用Qt风格代码注释,即在C风格注释块开始处添加一个叹号'!':

6./*!

7.*...描述...

8.*/


注释块中间的星号是可选,所以将注释块写成:

/*!

...描述...

*/


同样也是有效的.
9.第三种方法就是使用连续两个以上C++注释行所组成的注释块,而每个注释行开始处要多写一个斜杠或写一个叹号。像下行这样:

10.///

11.///...描述...

12.///


或者

//!

//!...描述...

//!


13.一些人喜欢使他们的注释块在文档中显得更为显目,所以你也可以这么做:

14./////////////////////////////////////////////////

15.///...描述...

16./////////////////////////////////////////////////


简述同样也可以同种写法:
1.一种是在一个doxygen注释块中使用"brief.这个命令只对当前一个文字段有效,所以详细描述应该与之间隔一个空行.
像这样:

/*!"brief这里是简要描述.

*这里仍然是简要描述.

*

*详细描述从这里开始.

*/


2.如果在doxygen配置文件将JAVADOC_AUTOBRIEF设置成
YES
。则JavaDoc风格将注释块中的第一个句子视为简要描述,这个句子可以以句号'.'、空格或者空行来结束:

3./**这里是简述,并由句号结束.详细描述从这里

4.*开始.

5.*/


这个功能同样多行C++行注释段中有效:

///这里是简述,并由句号结束.详细描述从这里

///开始..


6.第三种方法就是详细描述注释段紧跟在一行C++注释段后面,至多隔一个空行,如下面两个例子:

7.///简述.

8./**详细描述.*/


或者

//!简述.


//!详细描述

//!从这里开始.


注意最后一个例子,例子那个空行是用来分隔简述注释段和详细描述段的,不能去掉.而且JAVADOC_AUTOBRIEF不应该被设置成
YES.

看上去doxygen是相当富有弹性,但下面的例子是非法的:

//!这个简述因为是多行的

//!会被认为是详细描述..

/*!而这里则是另外的详细描述.

*/


因为doxygen只允许一个简要和一个详细描述。
此外,如果在一个代码项的声明之前有简要描述而且在其定义之前也有简要描述,那么doxygen只使用声明之前的描述。而如果详细描述出现了同样的情况,doxygen则会使用定义之前的描述,另外的描述会被忽略掉。
这里有一个使用Qt风格的C++代码:

//!Atestclass.

/*!

Amoreelaborateclassdescription.

*/


classTest

{

public:


//!Anenum.

/*!Moredetailedenumdescription.*/

enumTEnum{

TVal1,/*!<EnumvalueTVal1.*/

TVal2,/*!<EnumvalueTVal2.*/

TVal3/*!<EnumvalueTVal3.*/

}

//!Enumpointer.

/*!Details.*/

*enumPtr,

//!Enumvariable.

/*!Details.*/

enumVar;


//!Aconstructor.

/*!

Amoreelaboratedescriptionoftheconstructor.

*/

Test();


//!Adestructor.

/*!

Amoreelaboratedescriptionofthedestructor.

*/

~Test();


//!Anormalmembertakingtwoargumentsandreturninganintegervalue.

/*!

"paramaanintegerargument.

"paramsaconstantcharacterpointer.

"returnThetestresults

"saTest(),~Test(),testMeToo()andpublicVar()

*/

inttestMe(inta,constchar*s);


//!Apurevirtualmember.

/*!

"satestMe()

"paramc1thefirstargument.

"paramc2thesecondargument.

*/

virtualvoidtestMeToo(charc1,charc2)=0;


//!Apublicvariable.

/*!

Details.

*/

intpublicVar;


//!Afunctionvariable.

/*!

Details.

*/

int(*handler)(inta,intb);

};



点击这里查看doxygen产生的HTML文档.

只有一行的注释段包含的是简述,而多行的注释段则包含的是详细描述.
简要描述可以被用来进行class、namespace或者文件的成员描述,被以较小的斜体字型显示出来。(这种描述可以通过将BRIEF_MEMBER_DESC设置成NO来隐藏。)默认情况下,简要描述会被显示成详细描述的第一个句子。(这同样可以通过将REPEAT_BRIEF设置成
NO
来屏蔽。)在Qt风格中,两种描述都是可选的。
默认情况下,JavaDoc风格的注释段和Qt风格的注释段的行为是相同的。但这样,就不符合JavaDoc标准,注释段的第一个句应该自动识别为简要描述。你应该设置JAVADOC_AUTOBRIEFylyYES,来启用这个功能。如果你设置了这个选项并想在句子中间放置一个句号,你应该在后面添加一个反斜杠和一个空格.就像下面的例子一样:

/**Briefdescription(e.g."usingonlyafewwords).Detailsfollow.*/


Hereisthesamepieceofcodeasshownabove,thistimedocumentedusingtheJavaDocstyleandJAVADOC_AUTOBRIEFsettoYES:

/**

*Atestclass.Amoreelaborateclassdescription.

*/


classTest

{

public:


/**

*Anenum.

*Moredetailedenumdescription.

*/


enumTEnum{

TVal1,/**<enumvalueTVal1.*/

TVal2,/**<enumvalueTVal2.*/

TVal3/**<enumvalueTVal3.*/

}

*enumPtr,/**<enumpointer.Details.*/

enumVar;/**<enumvariable.Details.*/


/**

*Aconstructor.

*Amoreelaboratedescriptionoftheconstructor.

*/

Test();


/**

*Adestructor.

*Amoreelaboratedescriptionofthedestructor.

*/

~Test();


/**

*anormalmembertakingtwoargumentsandreturninganintegervalue.

*@paramaanintegerargument.

*@paramsaconstantcharacterpointer.

*@seeTest()

*@see~Test()

*@seetestMeToo()

*@seepublicVar()

*@returnThetestresults

*/

inttestMe(inta,constchar*s);


/**

*Apurevirtualmember.

*@seetestMe()

*@paramc1thefirstargument.

*@paramc2thesecondargument.

*/

virtualvoidtestMeToo(charc1,charc2)=0;


/**

*apublicvariable.

*Details.

*/

intpublicVar;


/**

*afunctionvariable.

*Details.

*/

int(*handler)(inta,intb);

};



点击这里查看doxygen产生的HTML文档.
不像其它的文档系统,doxygen允许在代码项的定义之前面放置成员(包括全局函数)的注释。这种方法可以在源文件中进行文档注释工作。这就是使得头文件可以比较简洁,使代码的实现人员更容易阅读。比较折中的方案就是在声明的地方添加简要描述,在实现的地方添加详细描述。

在成员后面放置文档

如果你想对文件、结构体、联合体、类或者枚举的成员进行文档注释的话,并且要在成员中间添加注释,而这些注释往往都是在每个成员后面。为此,你可以使用在注释段中使用'<'标识
Herearesomeexamples:

intvar;/*!<Detaileddescriptionafterthemember*/


ThisblockcanbeusedtoputaQtstyledetaileddocumentationblockafteramember.Otherwaystodothesameare:

intvar;/**<Detaileddescriptionafterthemember*/


或者

intvar;//!<Detaileddescriptionafterthemember

//!


或者

intvar;///<Detaileddescriptionafterthemember

///


Mostoftenoneonlywantstoputabriefdescriptionafteramember.Thisisdoneasfollows:

intvar;//!<Briefdescriptionafterthemember


或者

intvar;///<Briefdescriptionafterthemember


Notethattheseblockshavethesamestructureandmeaningasthespecialcommentblocksintheprevioussectiononlythe<indicatesthatthememberislocatedinfrontoftheblockinsteadofaftertheblock.
Hereisanexampleoftheuseofthesecommentblocks:

/*!Atestclass*/


classTest

{

public:

/**Anenumtype.

*Thedocumentationblockcannotbeputaftertheenum!

*/

enumEnumType

{

intEVal1,/**<enumvalue1*/

intEVal2/**<enumvalue2*/

};

voidmember();//!<amemberfunction.


protected:

intvalue;/*!<anintegervalue*/

};


点击这里查看doxygen产生的HTML文档.
警告:
这种注释方法只能在成员和参数中使用。它们不能用在描述文件、类、联合体、名字空间和枚举本身。此外,在下一节提到的结构化命令(如
"class
)在这种注释段中是无效的。

在其它地方进行注释

虽然我们一般是在声明和定义的前面添加文档注释块,但也许出于某种情况需要将文档放在其它什么位置上。比如我们需要编写一段实际上不存在的文件的描述。因此,Doxygen允许将文档放置在任何位置。(除了在函数体内或在一个普通的注释段)
为了达到这种目的,你唯一要做的就是在注释段中使用结构化命令。
结构化命令(就像其它命令)由一个反斜杠(
"
),或JavaDoc风格中使用的
@
来做开头,后面紧跟着命令名字和一些参数。例如,你想注释一个名为
Test
的类,如下例:

/*!"classTest

"briefAtestclass.


Amoredetailedclassdescription.

*/


命令
"class
被用来指示代码段中包含着关于
Test
类的文档.其它的结构化命令有:
·
"struct
生成C结构的文档.
·
"union
生成联合体的文档.
·
"enum
生成枚举的文档.
·
"fn
生成函数的文档.
·
"var
生成变量或typedef或枚举值的文档.
·
"def
生成#define定义的文档.
·
"file
生成关于一个文件的文档.
·
"namespace
生成名字空间的文档.
·
"package
生成Java包的文档.
·
"interface
生成IDL接口的文档.
参看特殊命令得到更多关于这些命令或其它命令的详细信息.
对C++类的成员进行文档注释时,必须对类本身进行文档注释。这同样对名字空间有效。要对全局函数、typedef、枚举或宏定义进行文档注释,则必须先对包含它们的文件进行文档(这通常是头文件).
再重复一下,因为它经常被忘记:如果要对全局项目(如:函数、typedefs、枚举或宏等),你必须必须对定义它们的文件进行文档注释。换一句话,你至少在文件写下

/*!"file*/




/**@file*/


这样的注释.
下面是一个名为structcmd.h头文件的例子,里面包含了使用结构化命令的例子:

/*!"filestructcmd.h

"briefADocumentedfile.


Details.

*/


/*!"defMAX(a,b)

"briefAmacrothatreturnsthemaximumof"aaand"ab.


Details.

*/


/*!"vartypedefunsignedintUINT32

"briefAtypedefinitionfora.


Details.

*/


/*!"varinterrno

"briefContainsthelasterrorcode.


"warningNotthreadsafe!

*/


/*!"fnintopen(constchar*pathname,intflags)

"briefOpensafiledescriptor.


"parampathnameThenameofthedescriptor.

"paramflagsOpeningflags.

*/


/*!"fnintclose(intfd)

"briefClosesthefiledescriptor"afd.

"paramfdThedescriptortoclose.

*/


/*!"fnsize_twrite(intfd,constchar*buf,size_tcount)

"briefWrites"acountbytesfrom"abuftothefiledescriptor"afd.

"paramfdThedescriptortowriteto.

"parambufThedatabuffertowrite.

"paramcountThenumberofbytestowrite.

*/


/*!"fnintread(intfd,char*buf,size_tcount)

"briefReadbytesfromafiledescriptor.

"paramfdThedescriptortoreadfrom.

"parambufThebuffertoreadinto.

"paramcountThenumberofbytestoread.

*/


#defineMAX(a,b)(((a)>(b))?(a):(b))

typedefunsignedintUINT32;

interrno;

intopen(constchar*,int);

intclose(int);

size_twrite(int,constchar*,size_t);

intread(int,char*,size_t);


点击这里查看doxygen产生的HTML文档.
因为例子中的每个注释都包含了结构化命令,所以所有的注释块都可以移动到其它的地方,而不会对生成的文档产生影响。这种方法的坏处是当原型发生了改变,你不得不改变结构化命令的参数。因此,在使用它们之前,应该认真考虑一下是否真正需要使用它们。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: