为代码生成文档标注基础
您可以使用JavaDoc风格,类似于由C风格的注释块:
/*** ... 文本 ...*/
此外您也可以使用Qt风格,如
/*!* ... 文本...*/
以上两种风格中间的*是可选的,也就是下面这样写也是可以的:
/*!... 文本...*/
第三种是使用至少两行C++"//"注释,如:
// ... 文本...///
或者
//!
//!...文本...
//!
有的程序员也许喜欢下面这种风格,有比较好的视觉效果:
... 文本.../
对于简单的描述信息,可能有几种情况。一种是在注释块的开头使用/brief命令,该命令一直到段落结束有效,所以详细描述信息从空一行后开始,如下例:
/*! /brief 简洁的描述信息 description.* 又一些简洁的描述信息。** 详细描述信息从这里开始。*/
在配置文件中,如果JAVADOC_AUTOBRIEF设为YES,则Doxygen将使用JavaDoc风格的注释块,从简洁描述信息后的点空格. 开始为详细描述信息,例如:
/** 简洁信息结尾是一个点号. 详细描述信息从* 这里开始*/
该选项对C++风格的多行注释也是有效的:
///简洁信息结尾是一个点号. 详细描述信息从///这里开始
或者:
/// 简洁描述信息/** 详细描述信息*/
或者:
//!简洁描述信息//!详细描述信息从//!这里开始
此例中间空行用来分割简洁描述信息块和详细描述信息块。可见doxygen的文档标注使用格式是非常自由的。不过要注意下面格式是不合法的,因为doxygen只允许一块详细描述信息对应一块简洁描述信息:
//!简洁描述信息//! 详细描述信息/*! 注意,又一详细描述信息!*/
下例使用Qt风格的文档标注://! A test class. /*!A more elaborate class description.*/class Test{ public: //! An enum. /*! More detailed enum description. */ enum TEnum { TVal1, /*!< Enum value TVal1. */ TVal2, /*!< Enum value TVal2. */ TVal3 /*!< Enum value TVal3. */ } //! Enum pointer. /*! Details. */ *enumPtr, //! Enum variable. /*! Details. */ enumVar; //! A constructor. /*! A more elaborate description of the constructor. */ Test(); //! A destructor. /*! A more elaborate description of the destructor. */ ~Test(); //! A normal member taking two arguments and returning an integer value. /*! /param a an integer argument. /param s a constant character pointer. /return The test results /sa Test(), ~Test(), testMeToo() and publicVar() */ int testMe(int a,const char *s); //! A pure virtual member. /*! /sa testMe() /param c1 the first argument. /param c2 the second argument. */ virtual void testMeToo(char c1,char c2) = 0; //! A public variable. /*! Details. */ int publicVar; //! A function variable. /*! Details. */ int (*handler)(int a,int b);};
Doxygen里如何分组 from http://leal.blogchina.com/ http://www.stack.nl/~dimitri/doxygen/grouping.html http://www.stack.nl/~dimitri/doxygen/commands.html
分组
Doxygen有三种机制可供分组。其一,工作在全局层次上(global level),为每个组创建一个新页(指在生成的文档中)。这些组在文档里被称为'modules'。 其二,工作在复合实体(如enum,struct等)的成员列表内,被称为'member groups'。其三,对于pages 有一称为subpaging 的分组机制。
Modules 模块
Modules是将相关事物分组至一个单独页面(指在生成的文档中)的方法。你可以分别文档化一个组的所有成员,也可以整体方式文档化一个组。组的成员可以是files, namespaces, classes, functions, variables, enums, typedefs和defines,以及其它组。
要定义一个组,应在专用注释块里添加/defgroup 命令。该命令的第一个参数是个唯一性标签(label),用来标识一个组。第二个参数是在生成的文档中出现的该组的名字或标题。
/defgroup (group title)
表明所在注释块包含了一组classes, files或namespaces的文档说明。 可以对classes, files 或 namespaces进行分类,并文档化这些分类。组可以是其它组的成员,这样可以构建有层次结构的groups。
参数必须是单个字(single-word)的标识符。
See also:page Grouping, sections /ingroup, /addtogroup, /weakgroup.
在实体(指class, function, etc.)的注释块里添加/ingroup命令,可以把该实体添加到一个特定组里。
为免于要在每个成员的注释块里添加/ingroup命令之苦,也可以在一个组的前面和后面分别放置展开标记(open marker)@{和闭合标记(close marker)@},两个标记之间的实体都成为该组的成员。这两个标记可以放在组定义的注释块或一个单独的文档注释块里。
/ingroup ( [ ])
如果一个class, file或namespace 的注释块里有/ingroup命令,则这个class(或其它实体)便会被添加到当前组内,或者由标识的组内。
See also:page Grouping, sections /defgroup, /addtogroup and /weakgroup
Groups也可以用这些分组标记进行循环嵌套。
多次使用同一个组标签(group label)会导致出错。如果你不希望受doxygen牵制必须使用唯一性标签,那么可以用 /addtogroup 来替代 /defgroup 。其用法和几乎一致,但是遇到已被定义的组,该命令会悄无声息的自动合并已有文档和新的文档注释。对该命令而言,组的标题是可选的,因此你可以用(全文的注释风格皆已改为Qt风格)
/*! /addtogroup */
/*/@{*/
/*/@}*/
把另外的成员加到一个组内,该组更多的内容则是定义在其它地方。
注意,复合实体(如classes, files 和namespaces等)可被加到多个组内,但成员(如variable, functions, typedefs和enums等)只能是某一个组的成员(这一限制是为了避免模棱两可的连接目标,因为class, namespace或file的成员有可能并未加以文档注释,而只是作为一个组的部分才可见)。
Doxygen会把其定义有最高「优先权」的成员加到组里,也就是说一个显式的/ingroup命令会使得由@{和@}界定的隐式分组定义无效。除非某个成员的其中一个定义没有任何显式的文档注释,不同组定义内该成员(因为一个实体可能在多个组的定义中出现,尤其是使用@{和@}时)的分组定义优先权一样的话,会引发警告。(Conflicting grouping definitions with the same priority trigger a warning, unless one definition was for a member without any explicit documentation.)
下面的示例把VarInA加到组A,并通过把IntegerVariable加到组IntVariables内而悄悄的解决了它引起的冲突,因为IntegerVariable第二次出现时并未加以文档注释(下面示例必读,尤其是我注释的部分:))。
/*!
* /ingroup A
*/
extern int VarInA;
/*!
* /defgroup IntVariables Global integer variables
*/
/*@{*/
/*! an integer variable */
extern int IntegerVariable;
/*@}*/
....
/*!
* /defgroup Variables Global variables
*/
/*@{*/
/*! a variable in group A */
int VarInA;
int IntegerVariable;
//此处IntegerVariable第二次出现,并且在组Variables定义内,但并未加以
//文档注释,但组IntVariables内IntegerVarible第一次出现时有文档注释(优
//先权更高),因此这儿的IntegerVariable并不会因为被包含在@{和@}内而加
//到当前组A内。
//如果上行代码前加入和前面优先权一样的/*! an integer variable same!*/
//文档注释块,则用doxygen生成文档时会引发警告;
//如果上行代码前加入比前面优先权更高的/*! IntegerVariable will be in
//group Variables! */文档注释块,则IntegerVariable加入组Variables。
/*@}*/
/ref 命令用于参考(提及)一个组,第一个参数应该是要参考组的标签。如果想使用自定义的链接名,可以给这些链接名加上双引号(不能用中文输入法下的),并将其放在第一个参数组标签之后,下面的例子会演示其用法。
总之,用/ref group_label "link"时,点击"link"链接名时便能链接到这个组。
分组定义的优先权从高到低依次为:/ingroup, /defgroup, /addtogroup, /weakgroup。最后那个命令几乎和/addtogroup完全一样,就是优先权更低而已,它的引入是为了允许"懒惰"的分组定义方式:你可以在.h文件里使用优先权更高的命令定义组层次结构,而在.c文件里则用/weakgroup命令,这样就不用非得和.h定义的组层次结构一摸一样。(因为.h里优先权更高的命令会使.c里对应实体的优先权低的分组命令无效。)
Example:
/*! /defgroup group1 The First Group
* This is the first group
* @{
*/
/*! /brief class C1 in group 1 */
class C1 {};
/*! /brief class C2 in group 1 */
class C2 {};
/*! function in group 1 */
void func() {}
/*! @} */ // end of group1
/*!
* /defgroup group2 The Second Group
* This is the second group
*/
/*! /defgroup group3 The Third Group
* This is the third group
*/
/*! /defgroup group4 The Fourth Group
* /ingroup group3
* Group 4 is a subgroup of group 3
*/
/*!
* /ingroup group2
* /brief class C3 in group 2
*/
class C3 {};
/*! /ingroup group2
* /brief class C4 in group 2
*/
class C4 {};
/*! /ingroup group3
* /brief class C5 in @link group3 the third group@endlink.
*/
class C5 {};
/*! /ingroup group1 group2 group3 group4
* namespace N1 is in four groups
* /sa /link group1 The first group/endlink, group2, group3, group4
*
* Also see /ref mypage2
*/
namespace N1 {};
/*! /file
* /ingroup group3
* /brief this file in group 3
*/
/*! /defgroup group5 The Fifth Group
* This is the fifth group
* @{
*/
/*! /page mypage1 This is a section in group 5
* Text of the first section
*/
/*! /page mypage2 This is another section in group 5
* Text of the second section
*/
/*! @} */ // end of group5
/*! /addtogroup group1
*
* More documentation for the first group.
* @{
*/
/*! another function in group 1 */
void func2() {}
/*! yet another function in group 1 */
void func3() {}
/*! @} */ // end of group1
单击here 浏览由Doxygen生成的对应HTML文档。
Member Groups 成员组
如果一个复合体(如a class或file)有许多成员,那么通常的做法是对这些成员进行分组。其实Doxygen已经自动根据成员的类型和保护级别(type and protection level)对它们进行分组,但是你可能觉得这还不够好或者缺省分组根本就不对。比如,你会认为不同(语法上的 syntactic)类型的成员应该归类到同一组内(语义上的 semantic)。
成员组由如下块定义(统一使用下面的注释块):
//@{
...
//@}
块或者
/*@{*/
...
/*@}*/
块,如果更喜欢C风格注释。注意,该组的所有成员必须物理上(即不像模块组那样随意,且有/addgroup等命令)都在这个成员组的体内(即上面的注释块内)。
可以在成员组注释块的展开标记(//@{)之前加一个独立注释块,该注释块里应该含有@name (或/name 统一使用这种写法),用来指定这个组的题头。另外,该注释块也可以包含关于这个组详细描述。
成员组不允许嵌套。
如果一个class内的成员组的所有成员具有相同类型和保护级别(比如都是静态公用成员),那么整个成员组会作为这种类型/保护级别组的子组(subgroup)显示在文档中(比如这个组作为"Static Public Members" section的subsection显示)。如果两个或两个以上成员的类型不同,那么这个组会和自动生成的组作为同一层(即不会作为自动生成的组之subsection)显示在文档中。如果你想强行令一个class的所有member-groups都显示在顶层里,则应该在该class的文档注释块里加上/nosubgrouping命令。
Example:
/*! A class. Details */
class Test
{
public:
//@{
/*! Same documentation for both members. Details */
void func1InGroup1();
void func2InGroup1();
//@}
/*! Function without group. Details. */
void ungroupedFunction();
void func1InGroup2();
protected:
void func2InGroup2();
};
void Test::func1InGroup1() {}
void Test::func2InGroup1() {}
/*! /name Group2
* Description of group 2.
*/
//@{
/*! Function 2 in group 2. Details. */
void Test::func2InGroup2() {}
/*! Function 1 in group 2. Details. */
void Test::func1InGroup2() {}
//@}
/*! /file
* docs for this file
*/
//@{
//! one description for all members of this group
//! (because DISTRIBUTE_GROUP_DOC is YES in the config file)
#define A 1
#define B 2
void glob_func();
//@}
单击 here浏览由Doxygen生成的对应HTML文档。
此处Group1作为"Public Members"的一个subsection显示在文档中,而Group2是作为一个单独section(和"Public Members"同一层)显示,因为它的成员有不同的保护级别(即public和protected)。
Go to the next section or return to the index.
Subpaging 分页
/page和/mainpage命令可以把信息分组到不同的页面。一般来说,这会生成一组flat(无层次关系的)页面,而所谓的"main"页面会作为该列表第一项显示。
使用section modules里的方法添加结构虽然可行,不过通常更自然方便的方法是用/subpage命令把其它结构添加到不同页面里。
页面A里用/subpage命令添加一个到另一页面B的链接时,会同时使得页面B成为A的一个subpage。这样做的效果可类比于:做两个组GA和GB,并且GB是GA的一部分,页面A放在组GA里,而页面B放在组GB里。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yaosan/archive/2009/02/11/3877500.aspx