doxygen教程-6-把注释放在其他位置

把注释放到成员之后

这里出现了新词"成员(member)", 在官方手册里也是直接就用了这个词, 而没有给出定义. 我们已经知道, 结构体, 枚举等类型内部声明的变量被称为 member, 而根据官方手册给出的例子来看, 全局变量也被当作 member. 把全局变量看成是文件的 member, 也说得通.

在前面的介绍中, 我们都是把注释放在函数之前的, 而对于结构体, 联合, 枚举这些复合类型, 把注释放到它们的成员的后面或许会更方便.

对于变量, 我们通常也喜欢把注释放到定义的后边. 要做到这一点, 语法很简单, 只要在前面注释的基础上, 多加一个小于号 < 就成了, 例如:

int var1; /*!< Detailed description after the member in Qt style */
int var2; /**< Detailed description after the member in Javadoc style */
int var3; //!< Detailed description after the member
          //!<

同样, 如果希望注释内容被当作 brief, 换成只有一行的单行注释即可:

int var; //!< Brief description after the member
int var; ///< Brief description after the member

举个例子, 下面定义了两个全局变量, 其中一个注释在定义前, 而另一个注释在定义后:

/// Brief before global variable
int var1;

int var2;  ///< Brief after a global variable;

输出如下:

在这里插入图片描述

这种方法也可以用来注释函数的参数, 例如:

/** A func to test inline documentation. */
void many_params(
    int a,  ///< [in] pass in a
    int b,  ///< [in] pass in b
    int *c  ///< [out] pass out c    
);

其中 [in], [out] 表示函数参数的数值传递的方向, 用法与 @param 命令相同. 这个注释输出成网页是这个样子的:

在这里插入图片描述

上述注释除了多了 < 符号之外, 和前文介绍的 special comment block 的含义和结构是一样的. 但是有一个限制, 就是只能用于注释成员(members)参数(parameters), files, classes, unions 等类型自身不能使用这种注释.

注释在头文件和源文件的分布

通常将 C 语言的代码组织成头文件和源文件两部分,头文件中放各种声明,源文件放定义。我们希望可以通过头文件快速浏览有哪些可用的接口,而对于源文件的函数定义,我们则希望可以看到详细的说明。因此,为了保持头文件紧凑,我们可以只在头文件里写 brief,提供必要的简介,而在源文件里写 detail,从而开发者可以在研究函数实现的同时,方便地看到详细的介绍。

Structural commands

把注释放到(几乎)任意位置

目前为止, 我们已经知道如何把注释块放到被注释的 entity 的前边或后边, 而 doxygen 实际上支持把注释块放到几乎任何地方(除了函数体内或普通的C注释内).

在 Special commands 中, 有一类命令称为 Structural Commands, 利用这类指令, 我们可以在一处写代码, 而把注释放到很远的其他地方, 甚至可以是另一个文件. 例如

/** @fn fun()
    A function at another file.
*/

这里, @fn 命令指出这个注释的内容是函数 fun() 的文档. 其他的 structural commands 如下:

命令使用对象
@struct结构体
@union联合
@enum枚举
@fn函数
@var变量, typedef 或 enum 的值
@def#define
@typedef类型定义
@namespace命名空间
@packageJava package
@interfaceIDL interface

下面是官方手册上, 一个具体的例子(简洁起见, 做了些删改):

/*! @file structcmd.h
    @brief A Documented file.
    Details.
*/
/*! @def MAX(a,b)
    @brief A macro that returns the maximum of \a a and \a b.
    Details.
*/
/*! @var typedef unsigned int UINT32
    @brief A type definition for a .
	Details.
*/
/*! @var int errno
    @brief Contains the last error code.
    @warning Not thread safe!
*/
/*! @fn int open(const char *pathname,int flags)
    @brief Opens a file descriptor.
    @param pathname The name of the descriptor.
    @param flags Opening flags.
*/
/*! @fn int close(int fd)
    @brief Closes the file descriptor \a fd.
    @param fd The descriptor to close.
*/

#define MAX(a,b) (((a)>(b))?(a):(b))
typedef unsigned int UINT32;
int errno;
int open(const char *,int);
int close(int);

也可以把本例的注释放到别的文件中. 如果文件扩展名是 .dox, .txt, .doc, .md, 默认这些文件会被 doxygen 读取, 但不会显示在文件列表中, 所以可以考虑把本例中的注释放到 .dox 或 .txt 文件中, 以保持输出文档的整洁.

值得注意的是, 采用 structural commands 注释, 要多写一次变量定义, 函数原型等, 所以后续修改代码时, 要同时修改两处(代码和注释). 而且, 把注释放在远离被注释的 entity 的地方, 不太方便查看. 因此, 除非有什么特殊的理由迫使你这样做, 否则采用 structural commands 通常不是个好主意.

只有先注释高层级的结构, 才会显示低层级的注释

前面也已经提到过, 在默认配置下要在输出的文档中显示注释的内容, 代码中至少要有一句 /** @file */. 这里把官方手册的原文摘录如下:

To document a member of a C++ class, you must also document the class itself. The same holds for namespaces. To document a global C function, typedef, enum or preprocessor definition you must first document the file that contains it (usually this will be a header file, because that file contains the information that is exported to other source files).

大意是, 要注释一个 C++ 类的成员, 必须先注释这个类它本身. 要注释一个全局的 C 函数, typedef, enum 或 #define, 也必须先注释这个文件.

在注释全局对象(函数, typedef, enum等), 必须先注释这些对象所在的文件这一点常常被忽略, 所以再次提醒.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值