Java有好用的JavaDoc文檔生成工具,那么C++有沒(méi)有呢?有,這就是大名鼎鼎的Doxygen,開(kāi)源,功能強(qiáng)大,支持非常多的編程語(yǔ)言。
1. 安裝和配置
首先下載Doxygen1.5.6,然后下載graphviz-2.18,安裝。
運(yùn)行Doxywizard,開(kāi)始配置。
單擊Wizard按鈕,會(huì)彈出對(duì)話框,輸入項(xiàng)目名,這個(gè)名字會(huì)作為文檔的大標(biāo)題,輸入版本,也會(huì)出現(xiàn)在文檔中,然后輸入源代碼的根目錄,勾選”Scan recursively”,輸入文檔輸出路徑。如圖1所示:
圖1
單擊Mode標(biāo)簽,不做任何改動(dòng),保持默認(rèn)。
單擊Output標(biāo)簽,選擇“prepare for compressed HTML(.chm)”,因?yàn)槲冶容^喜歡chm,去掉LaTex。如圖2所示:
圖2
單擊Diagrams標(biāo)簽,如果已經(jīng)安裝了GraphViz,則保持默認(rèn),如果沒(méi)安裝,則選擇“Use built-in class diagram generator”,如圖4所示:
圖3
點(diǎn)擊OK,返回。
單擊Expert按鈕,會(huì)彈出一個(gè)有更多標(biāo)簽頁(yè)的對(duì)話框,在"Project"標(biāo)簽頁(yè)下,將OUTPUT_LANGUAGE設(shè)置為Chinese,因?yàn)槲倚枰芍形奈臋n,如圖4所示:
圖4
單擊"Input"標(biāo)簽,將INPUT_ENCODING保持默認(rèn)的utf-8,因?yàn)槲矣玫氖?/span>Visual Studio源代碼文件的編碼默認(rèn)就是utf-8。如圖5所示:
圖5
如果你有潔癖,你可以耐心的將FILE_PATTERNS下的后綴一個(gè)一個(gè)刪掉(用記事本打開(kāi)配置文件,搜索”FILE_PATTERNS”,一下可以刪 除一片,免去你點(diǎn)鼠標(biāo)點(diǎn)到食指抽筋之苦),只留下*.h、*.hpp、*.c、和*.cpp等,意思是只掃描C++頭文件和源文件,如圖6所示:
圖6
下拉滾動(dòng)條,會(huì)有EXCLUDE和EXCLUDE_PATTERNS表示不要進(jìn)行解析的目錄和文件,即工程目錄下有的目錄不需要進(jìn)行文檔化(比如測(cè)試代碼),就用這兩個(gè)排除掉。
單擊“Source Browser”標(biāo)簽,勾選“SOURCE_BROUSER”,這樣文檔中就會(huì)附加一份源碼,方便隨時(shí)查閱,如圖7所示:
圖7
單擊"HTML"標(biāo)簽,勾選“HTML_DYNAMIC_SECTION”,表示要輸出chm文件,同時(shí)在CHM_FILE輸入文件名作為要最終生成的chm文件名,旁邊的那個(gè)"File.."按鈕其實(shí)沒(méi)用。同時(shí)點(diǎn)擊“HHC_LOCATION”右邊的按鈕找到chm編譯器hhc.exe。如圖8所示:
圖8
單擊OK返回,接下來(lái)按“Save...”按鈕保存配置文件,文件名隨意,如圖9所示:
圖9
這個(gè)配置好的文件以后可以重復(fù)利用,每次點(diǎn)”Load…”裝載進(jìn)來(lái),然后點(diǎn)擊”Wizard…”,根據(jù)不同的工程,修改工程名字,版本,源代碼根目錄,文檔輸出目錄就可以了,不用再重復(fù)上述配置。
接下來(lái)在輸入Working Directory中一般也輸入源代碼的根目錄,主要是因?yàn)榕渲玫囊恍┻x項(xiàng)中有的可以用相對(duì)路徑,這個(gè)就可以作為相對(duì)路徑的參照點(diǎn)。
最后,還要用記事本打開(kāi)這個(gè)配置文件,找到JAVADOC_AUTOBRIEF,將它的值改為YES,即支持JavaDoc的語(yǔ)法,這樣就可以用熟悉的JavaDoc風(fēng)格的文檔注釋了。
最后單擊“Start”按鈕開(kāi)始生成文件,到D:/test下查看,發(fā)現(xiàn)多了個(gè)html文件夾,進(jìn)去一看,有很多HTML和一個(gè)chm文件,chm文件就是我們所要的文檔,不過(guò)還不行,chm的左邊導(dǎo)航目錄是亂碼,還需要一些步驟。
首先用一個(gè)文本編輯工具(我用VS2008打開(kāi),可以顯示中文,以gb2312另存的,可是VS2005貌似打開(kāi)是亂碼)打開(kāi)index.hhc文件,因?yàn)檫@個(gè)文件就是目錄,然后另存為gb2312編碼的文件,覆蓋原來(lái)的index.hcc。
然后用hhc編譯器重新編譯,把chm工程文件傳給hhc.exe即可,如圖10所示:
圖10
打開(kāi)docs.chm,目錄是中文的了!
2. 常用注釋語(yǔ)法
注釋寫(xiě)在對(duì)應(yīng)的函數(shù)或變量前面。
簡(jiǎn)要注釋和詳細(xì)注釋?zhuān)?br> /**
* @brief Brief Description.
*
* Detailed Description
*/
簡(jiǎn)要注釋和詳細(xì)注釋用一個(gè)空行隔開(kāi)。
J avaDoc風(fēng)格下,自動(dòng)會(huì)把第一個(gè)句號(hào)前的文本作為簡(jiǎn)要注釋?zhuān)竺娴臑樵敿?xì)注釋。你也可以用空行把簡(jiǎn)要注釋和詳細(xì)注釋分開(kāi)。注意要設(shè)置JAVADOC_AUTOBRIEF設(shè)為YES。
為了注釋一個(gè)類(lèi)中的member,首先要對(duì)該類(lèi)作注 釋。同樣的問(wèn)題上升到namespace。要注釋一個(gè)全局的function,typedef,enum或preprocessor定義,你需要首先定義 (只能用@file,因?yàn)槲募辉偃魏螙|西里面,就只能用特殊命令實(shí)現(xiàn)了,而不像類(lèi)、函數(shù)等,既可以在上方放注釋?zhuān)部梢杂聾class、@fn進(jìn)行注 釋?zhuān)┌奈募?/font>
(1)文件頭注釋
/** @file [file-name]
*@brief brief description.
* @author <list of authors>
* [@author <authors description>]
* @date <date>
* @version <version number>
*
* detailed description for test.cpp
*/
一般@file后我們空著,Doxygen會(huì)默認(rèn)為是@file所在文件的文件名。
[]表示可選,{}表示重復(fù)0到N次,<>表示必須參數(shù)。@author 表示作者,@data表示日期,@version表示版本號(hào)。
(2)類(lèi)注釋
/**
* @class <class-name> [header-file] [<header-name]
* @brief brief description
*
* detailed description
*/
header-file是類(lèi)聲明所在的頭文件名字,header-name是要顯示的鏈接文字,一般為頭文件的真實(shí)路徑。
(3)函數(shù)注釋
/**
* @brief brief description.
* {@param <parameter-name> <parameter description>}
* @exception <exception-object> <exception description>
* {@exception <exception-object> <exception description>}
* @return <description of the return value>
* {@return <description of the return value>}
* @note <text>
* @remarks <remark text>
* {@remarks <remark text>}
* [@deprecated <description>]
* [@since when(time or version)]
* [@see references{,references}]
*/
@可用\代替,但我傾向于用@。
@param 參數(shù)名及其解釋?zhuān)ㄎ疫€習(xí)慣在param后加[IN]表示輸入還是輸出參數(shù))
@exception 用來(lái)說(shuō)明異常類(lèi)及拋出條件
@return 對(duì)函數(shù)返回值做解釋
@note 表示注解,暴露給源碼閱讀者的文檔
@remark 表示評(píng)論,暴露給客戶(hù)程序員的文檔
@since 表示從那個(gè)版本起開(kāi)始有了這個(gè)函數(shù)
@deprecated 引起不推薦使用的警告
@see 表示交叉參考
函數(shù)的詳細(xì)注釋用@note代替詳細(xì)注釋?zhuān)驗(yàn)樵敿?xì)注釋要空行隔開(kāi),容易忘記。
(4)成員注釋
/**< 或//<用來(lái)注釋成員,放在成員后面,格式如下:
int var; /**< Detailed description after the member */
int var; ///< Brief description after the member
此語(yǔ)法對(duì)函數(shù)成員也適用。
(5)枚舉類(lèi)型注釋
/** @brief Another enum, with inline docs */
enum AnotherEnum
{
V1, /**< value 1 */
V2 /**< value 2 */
};
一般約定:
(1)每個(gè).h和.cpp文件的頭部,必須要有簡(jiǎn)要注釋和詳細(xì)注釋?zhuān)?xí)慣用法如下:
/** @file
*@brief brief description.
* @author <list of authors>
* @date <date>
* @version <version number>
*
* detailed description for test.cpp
*/
(2)每個(gè)類(lèi)的聲明上方,必須要有簡(jiǎn)要注釋和詳細(xì)注釋?zhuān)?xí)慣用法如下:
/**
* @class
* @brief brief description
*
* detailed description
*/
(3)全局變量和全局宏必須要有注釋。
如果注釋較短,則可以在上方用
/** @brief some brief description */或右方用
///< some brief description。
進(jìn)行簡(jiǎn)要注釋。
(4)任何函數(shù)都必須要有簡(jiǎn)要注釋和詳細(xì)注釋?zhuān)?xí)慣用法如下:
/**
* @brief brief description.
* @param <parameter-name> <parameter description>
* @exception <exception-object> <exception description>
* @return <description of the return value>
* @note <text>
* @remarks <remark text>
*/
對(duì)于類(lèi)的函數(shù)成員,在頭文件的定義處進(jìn)行簡(jiǎn)要注釋?zhuān)旁谏戏剑?br> class Test
{
public:
/** @brief brief description */
int m_test(int a);
}
而在實(shí)現(xiàn)出給出詳細(xì)注釋?zhuān)?br> /**
* @param [IN] a a integer
* @exception none
* @return 0
* @note detailed description
* @remarks some remarks to be attentioned
*/
int Test::m_test(int a)
{
Return 0;
}
純虛函數(shù)由于沒(méi)有實(shí)現(xiàn)則簡(jiǎn)要注釋和詳細(xì)注釋不需分開(kāi)。
對(duì)于類(lèi)的數(shù)據(jù)成員,只在頭文件的定義處進(jìn)行簡(jiǎn)要注釋?zhuān)灰敿?xì)注釋??梢栽谏戏接?** @brief some brief description */或右方用///< some brief description。
(5)每個(gè)枚舉定義必須添加注釋,格式如下:
/** Another enum, with inline docs */
enum AnotherEnum
{
V1, //< value 1
V2 //< value 2
};
下面是一個(gè)簡(jiǎn)單的例子,完全符合約定:
/** @file
* @brief a brief description for the file.
* @author soulmachine
* @date 2008/07/02
* @version 0.1
*
* detailed description for test.cpp
*/
/** @brief global function, no details
* @note some details about global function
*/
void global_test();
/** @class Test test.h "inc/test.h"
* @brief A test class.
*
* A more elaborate class description.
*/
class Test
{
public:
/** @brief A enum, with inline docs */
enum TEnum {
TVal1, /**< enum value TVal1. */
TVal2, /**< enum value TVal2. */
TVal3 /**< enum value TVal3. */
}
//這里Doxygen對(duì)enumPtr的處理有點(diǎn)問(wèn)題
*enumPtr, ///< enum pointer.
enumVar; ///< enum variable.
/** @brief A constructor. */
Test();
/** @brief A destructor. */
~Test();
/** @brief a normal member taking two arguments and returning an integer value. */
int testMe(int a,const char *s);
/** @brief A pure virtual member.
* @param c1 [IN] the first argument.
* @param c2 [IN] the second argument.
* @see testMe()
*/
virtual void testMeToo(char c1,char c2) = 0;
int publicVar;//< a public variable.
/** @brief a function variable, note Details. */
int (*handler)(int a,int b);
/** @brief brief before delaration */
int m_func(int a);
};
/** A more elaborate description of the constructor. */
Test::Test()
{
}
/** A more elaborate description of the destructor. */
Test::~Test()
{
}
/**
* @param [IN] a an integer argument.
* @param [IN] s a constant character pointer.
* @return The test results
* @note Details.
* @par
* Another detail.
* @see Test()
* @see ~Test()
* @see testMeToo()
* @see publicVar()
*/
int Test::testMe(int a,const char *s)
{
return 0;
}
/**
* @param [IN] a a interger
* @return 0
* @note detailed description
* @remarks remarks,important
* @since 1.0
* @see testMeToo
*/
int Test::m_func(int a)
{
return 0;
}
百度博客限制文章長(zhǎng)度,郁悶死了,每次先從word粘到記事本,在粘到編輯器,然后調(diào)格式,太痛苦了。下面是PDF版本,不斷更新中......