内部库的Doxygen注释块应该放在哪里 - 在H文件还是CPP文件中?

119
常识告诉我们,Doxygen注释块必须放置在头文件中,其中包含类、结构体、枚举、函数声明等。我同意这是一个适用于将库分发为仅包含头文件和目标代码库的有力论据。
但是……当我开发一种公司内部(或自己的副业项目)完整源代码将被使用的库时,我考虑采用完全相反的方法。我的建议是在实现文件(HPP、INL、CPP等)中放置大型注释块,以避免对头文件中声明的类和函数接口造成混乱。
优点: - 头文件中没有杂乱的内容,只有函数分类。 - 当使用智能感知(Intellisense)预览注释块时,不会产生冲突。这是我在一个.h文件中为函数添加注释块,并在相同的.h文件中使用内联定义并从.inl文件中进行包含时观察到的缺陷。
缺点: - (显而易见的)注释块不在声明所在的头文件中。
那么,你认为怎样并可能提出建议?
8个回答

96

我喜欢利用名称可以在多个地方记录的事实。

在头文件中,我写下了该方法的简要说明并记录了所有的参数 - 这些参数比方法本身的实现更不容易改变,如果确实需要更改,则函数原型也必须相应更改。

我将长格式的文档放在源文件中,紧挨着实际的实现,这样可以在方法发展时进行细节更改。

例如:

mymodule.h

/// @brief This method adds two integers.
/// @param a First integer to add.
/// @param b Second integer to add.
/// @return The sum of both parameters.
int add(int a, int b);

mymodule.cpp

/// This method uses a little-known variant of integer addition known as
/// Sophocles' Scissors. It optimises the function's performance on many
/// platforms that we may or may not choose to target in the future.
/// @TODO make sure I implemented the algorithm correctly with some unit tests.
int add(int a, int b) {
  return b + a;
}

3
我喜欢这种方法,但它似乎与AUTOBRIEF不兼容。我想知道是否有配置解决方法可以消除生成的多个摘要。 - Aaron Wright
我也喜欢这种方法,它在实现上提供了很好的平衡。 - Xofo
我无法在我的机器上重现这个方法,使用的是Doxygen 1.8.15。参数文档未显示,只有简要和详细描述。 - punyidea
1
补充说明:将详细描述的位置改为函数块内部使我成功了。该描述现在附加在头部文档中的描述末尾。 - punyidea
理论上很好,但会导致信息重复 :( - undefined

88

将文档放在人们在使用和处理代码时可以阅读和编写的位置。

类注释放在类前面,方法注释放在方法前面。

这是确保事物得到维护的最佳方法。它还使您的头文件相对紧凑,并避免了人们更新方法文档导致头文件变脏并触发重建的问题。我实际上知道有人将此用作稍后编写文档的借口!


13
我曾痛苦地想起了为什么应该避免在头文件中添加文档注释——一位高级副总裁告诉我将方法注释放在类声明中,并且当我点击这些头文件时,发现自己实际上会把注释修改留到以后,因为这会导致长达45分钟的构建时间!请注意,我已尽力保持原意并使其更易于理解。 - Andy Dent
9
不是在点踩,只是有疑问:如果我试图弄清楚一个API(即使是内部的),我宁愿不必打开.cpp源代码并浏览所有代码以查找文档。我承认,如果您记录了除客户端视图以外的更多方法内容(例如如何执行操作),那可能会很麻烦,但您本来就不应该这样做,对吧? - T.E.D.
9
使用Doxygen生成文档的主要目的是为了能够访问所生成的文档。我们有一个内部Web服务器,上面存放着Doxygen生成的输出内容,我们可以在讨论中使用指向该服务器页面的链接。这也将类或方法的文档与讨论更广泛的设计问题的其他页面联系在一起。 - Andy Dent
1
决定实现讨论的公开程度是一个有趣的问题。当然,如果有特定的算法或副作用,作为库的客户端,我更愿意知道它们。有时只有维护者应该知道,而Doxygen有一种简单的方法来标记条件部分,因此您可以为不同的观点生成不同的文档。 - Andy Dent
1
不仅如此,头文件中的文档会污染它们并使它们不适合作为 API 快速参考。我经常在头文件中简要查看一些接口细节的提醒。如果头文件被注释污染了,那么快速提取有用信息就变得困难。如果我需要详尽的文档,而源代码无法使用,我会查阅生成的文档。 - Slava
显示剩余3条评论

24

在头文件中添加注释意味着如果更改了注释,则必须重新编译类的所有用户。对于大型项目,如果冒险花费接下来的20分钟重建所有内容,程序员将不太愿意更新头文件中的注释。

而且...由于你应该阅读HTML文档而不是浏览代码以获取文档,因此注释块在源文件中更难定位并不是一个大问题。


正确,但如果它是从工件库检索的动态库且您没有源文件,则这是一个大问题 :-) - jaques-sam

15

标题: 查看文件时,由于其他“噪音”较少,因此更容易阅读注释。

来源: 然后你可以在查看注释的同时使用实际可用的函数。

我们只使用在头文件中注释的全局函数和在源文件中注释的本地函数。如果需要,您还可以使用copydoc命令将文档插入到多个位置而无需多次编写(有利于维护)。

但是,您也可以使用简单的命令将结果复制到不同的文件文档中。例如:

我的file1.h

/**
 * \brief Short about function
 *
 * More about function
 */
WORD my_fync1(BYTE*);

我的file1.c

/** \copydoc my_func1 */
WORD my_fync1(BYTE* data){/*code*/}
现在你可以在两个函数中获得相同的文档。这样可以减少代码文件中的噪音,同时还能在最终输出的多个位置呈现一次编写的文档。

2
块何时被复制? - Mert Can Ergün

3

我使用QtCreator进行编程。一个非常有用的技巧是在函数或方法上按Ctrl-Click可以获取头文件中的声明。

当该方法在头文件中被注释时,你可以快速找到你要查找的信息。所以对我来说,注释应该位于头文件中!


2
我把所有东西都放在头文件里。 我记录了所有内容,但只提取出公共接口。

2

通常我会在.h文件中放置接口文档(\param、\return),在.c/.cpp/.m文件中放置实现文档(\details)。Doxygen将所有函数/方法文档组合在一起。


0
在C++中,有时实现可以分为头文件和.cpp模块。在这种情况下,将文档放入头文件似乎更加清晰,因为那是所有公共函数和方法都得到保证的唯一位置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接