所以我有一个简单的功能和一些文档:
/**
* @param[out] dest is overwritten by the second argument
* @param[in] src is value to overwrite the first argument with
*/
void Copy(int &dest, int src) { dest = src; }
可能不是很有用,但很明显输出dest
。但是,通过使用指针,这条线变得模糊:
void Copy(int *dest, int src) { *dest = src; }
dest
还应该是输出吗?指针的值不会被修改,只会被指向内存中的值。但我仍然可以说是的。继续:
void Write(FILE *fw, int src) { fwrite(&src, sizeof(src), 1, fw); }
现在这对我来说真的很可疑,我会将fw
标记为输入,尽管它在逻辑上是输出,并且FILE
结构的内容也会在此过程中被修改(但是一个对我来说很不透明。)
另一方面:
void Open(FILE &*fw, const char *filename) { fw = fopen(filename, "w"); }
显然是输出。 FILE
句柄由函数初始化,指针的值被覆盖。
将参数标记为输出是否有一个好的经验法则或推理?
我甚至不想像使用C ++那样进入[in,out]
参数,这些参数基本上都是[out]
个参数(例如,如果通过std::vector
传递输出,则函数需要获取一个实例作为输入,输出甚至可以重用存储。)
答案 0 :(得分:4)
Opinions vary,更不用说如何记录它们了。不过,它们是常用的,你的问题也是有效的。
参数是否应标记为[in]
,[out]
或[in,out]
取决于参数的用途。
通常,输出参数的目的是允许被调用函数在单个返回值不足时将附加信息传递给调用函数。这"附加信息"通过调用函数提供的引用参数传递。可以使用C ++引用运算符(&
)或指针来提供引用参数,这是一个略有不同的车辆但具有相同的结果。
所以如果参数的目的是允许被调用函数向调用函数提供信息,那么它应该在文档中被标识为输出。
如果通过参数向函数提供文件句柄或文件名,则该文件句柄或文件名将被视为 input 参数,即使该函数旨在写入文件。这是因为
如果使用参考参数在两个方向上传递信息,则应将其记录为[in,out]
。
<强>此外强>
记录函数时,请将该函数视为提供给调用者的服务。您的文档的读者是程序员编写将调用您的函数的代码。编写文档,就像您(函数的编写者)不知道调用代码的上下文或细节一样。本文档的目的是概括地描述函数的功能,并详细说明如何使用该函数。
因此,如果函数的设计者打算将dest
用作输出,则应将其标记为输出。当调用者对通过该输出提供的数据不感兴趣时,您还应该考虑这种情况。通常,调用者将空指针作为该参数的参数来指示。在将任何数据写入*dest
之前,您的函数应进行测试以确保dest
不为空。参数dest
的文档应说明如果dest
是空指针,则不会写入任何数据。
将const用于输入指针参数
另外,如果指针参数仅用于输入,则应使用const
关键字修改该参数,如下所示:
void Copy(int *dest, const int *src) { *dest = *src; }
这有以下好处:
Copy
函数的程序员错误地尝试这样做,它会阻止*src
函数写入Copy
位置Copy
的代码,使src
缓冲区不被Copy
修改const
时保持一致,则它是自我记录的:标记为const
的指针参数显然是仅输入的,而指针参数未标记为{{1}可能用于输出。另见