我想提高代码的可读性。所以,我在这样的代码注释的参数的方向:
#define IN
#define OUT
void Add(IN int Para1, IN int Para2, OUT int& Result);
但我认为,编译器将取代IN和OUT的每个实例有空白,它可能是一个相当问题的一些倍。
那么,有没有更好的办法?谢谢。
(I使用C ++。)
是:忘掉这些东西,并使用常量性。只要将工作,你没有一个“in”和“out”参数,这就是,应该很少使用。
void foo(int i, const std::string& s, std::vector<char>& out_buf);
// i and s are obviously "in" variables, while out_buf could be both,
// but you can easily show that by giving the parameter a proper name.
编辑:和const正确性并不意味着要做价值参数常量!这不会给来电者的其他信息在所有的,因为你不能改变他的变量两种方式。
您可以尝试把它的意见。这是好多了,可读。
void Add(/*IN*/ int Para1, /*IN*/ int Para2, /*OUT*/ int& Result);
我能想到的这两种简单的方法..
1.
/*Description : Function for adding the two variables.
* Returns : Nothing
* Parameters : Para1 and Para2 are **IN** parameter and
* Result is an **OUT** parameter
* @author : <put ur name here>
*/
void Add(IN int Para1, IN int Para2, OUT int& Result);
除了这些基本信息,您还可以存储信息,如版本号,创建日期等。
2.您还可以嵌入用即inPara1,inPara2和outResult变量名称参数类型信息。例如
void Add(int inPara1,int inPara2,int& outResult);
还有一件事我会建议使用骆驼情况下字母变量和函数的名称,即PARA1可以像PARA1等,这将有助于你在未来。
我用的是这样的
void Add(
/* input parameters */
int Para1,
int Para2,
/* output parameters */
int& Result
);
这使得添加新的参数功能容易,因为你没有给他们每个输入或输出标记,他们可以去相应的部分。
你可以做的“IN”变量const
,这意味着他们永远不会被修改,所以必须是唯一的输入变量。没有const
参考也可能意味着这将有它的内容修改,所以必须是“OUT”变量。不过说真的,只是下面的一个很好的变量命名约定应该够了。调用参数“结果”意味着它会本身就是一个“OUT”变量。
编辑:正如已经正确地被别人所提到的,像传递整型数值为const瓦尔可能不是一个好主意。然而,你应该能够推断出一个变量是否是眼前的事实,他们总是需要引用(或指针)的输出一个或没有。通过使该输入值常数引用,这意味着不是常量必须输出值的所有引用。
考虑到这是一个风格问题,它会引发一些主观感受,包括我。 :-)
有迹象表明,这样做需要的功能参数的程序语言在那里被定义为输入或输出。在C ++中,这是大可不必。
一般的心态,一个现代化的C ++开发者都应该是一个更侧重于可变与不可变的,并且接口通过原始类型和数据。
当我们看到这样的功能:
void f(int x);
...一个C ++开发人员可以一目了然告诉你,“X”是用于输入。为什么?它被按值传递。有没有办法在对来电者的任何影响,从而传递给这个函数任何参数是不会被修改的方式来修改“X”。
这也是任何常量引用真:
void f(const Foo& read_only_foo);
上述绝对是一个严格的输入参数。当我们看到这样的功能:
void f(int& x);
通常,我们可以假设f
是要修改x
(它不能保证,但知道什么f
不应该清除任何疑问)。
与用户定义的类型,它变得更加朦胧一点。
ostream& operator<<(ostream& os, const Foo& foo);
在这里,我们肯定知道“富”是一个输入参数,因为它是不可变的。但是,关于“OS”是什么?它是一个输出参数,输入,两者兼而有之?在严格的程序语言,输出参数通常将意味着该参数将被改变,但我们也从中读出在这里,所以这将是两者兼而有之。虽然我们将调用在“OS”是对其状态的效果的方法,它不正是我们在输入/输出参数本身支持的程序语言思考的输出参数的方式。
问题的关键是,考虑参数的这种严格的I / O方式可以得到这些类型的高级接口和面向对象的设计彻头彻尾的混乱。看看这里的东西更有用的方式往往是实现该接口的对象是否是可变的或不可变的。在这里,“OS”是可变的。该功能一般说,它会被调用修改其状态的一些功能。
这个怎么样?
// fills the specified list with stuff
void some_list(list<int>& out_list);
这往往会走,也许更自然,与那种语义我们预期的输出参数。喜欢的东西填充的列表中,我们往往会更直观地把它作为函数输出通过列表的结果。我甚至为前缀的名字与“出”来强调。但实际上,与C ++ 11特别是,我们不应该写这样的事情斯特劳斯强调:
// returns a new list filled with stuff
list<int> some_list();
这实际上留下极少数地方留在输入/输出的区分可以说是在所有非常有用的(而不是与已经提供标记参数为手段冗余可变/不可变的,按价值计算,引用,指针,或R值参考) 。
有什么功能是做清晰的文档相结合,一般不存在关于它如何与它的参数工作,所以输入/输出约定往往很少做,但增添了很多额外的代码不确定性,并可能促进更多的数据导向心态,你应该试图摆脱掉。
总而言之,我建议尽量避免这种约定放在一起。即使有赞成的也很好的理由,它只是没有什么人倾向于用C ++做。如果你希望人们享受与你的代码的工作,并没有感到沮丧,你必须学会什么普通群众往往理解和喜欢一起去。什么太奇特会吓到人了。
如果你是绝对的,狂热地连接到指定的一切作为或缩小,我建议像文档样式或命名约定最小侵入性的解决方案。绝对避免什么都不做的宏。这将需要你的读者,以检查每一次,这些宏做,事实上,什么也不做。命名约定或文档样式不需要这样的检查。
最后,从C的创造者有点报价++自己:
关于宏的第一条规则是:除非你要不要使用它们。几乎每一个宏演示的编程语言中的漏洞,在节目中,或程序员。 - 比亚内Stroustrup的
有两个方面是:函数签名,并调用点。您关注的签名,所以我先解决这个问题。笔记:
const
ness进行通信,并通过该功能强制潜在修改在客户端调用点,传递一个非const参数时,目前还不清楚会发生什么变化。
loadXXX
,组输出第一/最后,而宁愿到return
输出(S) - getXXX
- 上面提到的帮助客户端太约定。const
参数const
在调用点,他们将不会被修改进行沟通,但是这是冗长而乏味,和实践不能由编译器执行(编译器会阻止被调用的函数修改这些参数,但不能用力呼叫者提供参数的函数接受作为const
明确地投它const
)。有些东西可以“被迫”与代理对象,但它会使你的代码几乎读和难以维护。
使用适当的语言结构,而不是文物。
使用IN和OUT不授予他们真的IN和OUT。这就像匈牙利命名法,调用WPARAM
的东西,这是一个word
,今天是一个long
。
int
)传递是在你可以修改const int&
)传递是表现为在函数的常量的INint&
)通过是一个OUT必须是有const int*
)是也可以没有给出IN(空指针)int*
)是也可以没有任何OUT(空指针)使用正确的语言结构的优点是使用不当会导致编译错误(让你不得不纠正的问题),而IN和OUT绝不会产生任何类型的代码中的错误,并且你的风险引进一个正式的会议该-after维护releases-的特定数量可以甚至骗本身。
您可以使用C ++微软SAL符号:
从文档摘自:
该功能将只从缓冲区中读取。调用方必须提供缓冲区并对其进行初始化。
该功能只写缓冲区。调用者必须提供缓冲,该函数将初始化。
该函数可以自由地读取和写入到缓冲器。调用方必须提供缓冲区并对其进行初始化。
适用于被取消引用输出参数。给定一个参数p,* p是缓冲器指针。 p必须不为NULL。
该功能只写缓冲区。该功能将提供缓冲并对其进行初始化。