免责声明:我已经有一段时间没有使用 C++了...
现在装饰 C/C++ 函数/方法声明以提高可读性是否很常见?
粗略的例子:
void some_function(IN int param1, OUT char **param2);
使用空主体定义的宏IN和OUT(即,如果您愿意在本例中使用轻量级文档)。当然,我理解这与与方法/函数相关的“文档注释块”有些平行。
您能否提供一些其他示例...假设该主题对社区有用。请记住,上面的示例就是这样。
免责声明:我已经有一段时间没有使用 C++了...
现在装饰 C/C++ 函数/方法声明以提高可读性是否很常见?
粗略的例子:
void some_function(IN int param1, OUT char **param2);
使用空主体定义的宏IN和OUT(即,如果您愿意在本例中使用轻量级文档)。当然,我理解这与与方法/函数相关的“文档注释块”有些平行。
您能否提供一些其他示例...假设该主题对社区有用。请记住,上面的示例就是这样。
我不会欣赏这样的装饰。
使用 const 和引用以及常量引用要好得多,例如
void some_function(AClass const ¶m1, AnotherClass ¶m2)
通常 int 是通过值而不是通过引用传递的,所以我使用 AClass 和 AnotherClass 作为示例。在我看来,添加 empy IN 和 OUT 会分散注意力。
Windows 标头实际上就是这样做的。有关使用的注释的完整列表,请参阅标题注释。例如”
DWORD
WINAPI
GetModuleFileName(
__in_opt HMODULE hModule,
__out_ecount_part(nSize, return + 1) LPTSTR lpFilename,
__in DWORD nSize
);
对于这个函数,hModule
是可选的输入参数,lpFilename
是一个输出参数,最多存储nSize
字符元素,返回时将包含(函数的返回值)+1个字符元素,nSize
是一个输入参数。
出于文档目的,编写良好的注释块就足够了,因此这些没有任何用途。此外,一些文档注释解析器对这样的事情有特殊的语法;例如,给定 Doxygen,你可以这样写:
/**
* @param[in] param1 ...
* @param[out] param2 ...
**/
void some_function(int param1, char **param2);
我认为这是一个坏主意。特别是因为任何人都可以出现并定义宏 IN/OUT 并让您陷入大麻烦。
如果您真的想记录它,请在其中添加评论。
void some_function(/* IN */ int param1, /* OUT */ char **param2);
还有为什么在返回值可以正常工作时使用 out 。
此外,我更喜欢使用 pass by ref 和 const ref 来表明我的意图。此外,当您的代码是 const 正确时,编译器现在对意图进行了相对较好的优化。
void some_function(/* IN */ int const& param1, /* OUT */ char*& param2);
// OK for int const& is kind of silly but other types may be usefull.
不是在 C++ 中,我没有专业地做过 C 编程,但至少在 C++ 中,参数的类型是不言自明的:
void f( std::string const & ); // input parameter
void f( std::string ); // input parameter again (by value)
void f( std::string& ); // in/out parameter
std::string f(); // output
连同代码内文档工具(doxygen),您可以在其中向参数添加一些上下文(函数期望或不可接受的值,函数如何更改传入的对象......
关于指针:我们倾向于在方法接口中限制原始指针。需要时可以使用它们,但通常应该首选智能指针。再说一次,所有权语义来自智能指针的选择:shared_ptr<> 用于稀释共享责任(或在需要时),auto_ptr<>/unique_ptr<> 用于单一所有权(通常作为工厂、本地或成员属性的返回值)。 ..
我尝试使用:
大多数时候真的很容易看出哪些是 IN 或 OUT 参数,当然声明中的专有名称是一个很好的文档。
我发现那些 IN、OUT 插件很烦人。
我见过这个,但我不认为我会说它是“常见的”。
Win32 API(C 不是 C++)使用类似的东西:
WINADVAPI
BOOL
WINAPI
CreateProcessWithLogonW(
__in LPCWSTR lpUsername,
__in_opt LPCWSTR lpDomain,
__in LPCWSTR lpPassword,
__in DWORD dwLogonFlags,
__in_opt LPCWSTR lpApplicationName,
__inout_opt LPWSTR lpCommandLine,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCWSTR lpCurrentDirectory,
__in LPSTARTUPINFOW lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);
对于 Visual C++ 2005 和更高版本的编译器,这些实际上映射到声明,例如__$allowed_on_parameter
并在编译时进行检查。
唯一比这更糟糕的是很久以前在 Pascal dev 编写的 C 程序中看到的:
#define begin {
#define end }
int main( int argc, char* argv[] )
begin
...
end
我以前没见过这个。我认为最好将这样的信息放在评论中。
除了参数类型中的信息外,我还看到了前缀 i_、o_、io_ 的用法:
void some_function(int i_param1, char** o_param2, int& io_param3);