[C++] 使用'const'作为函数参数


Answers

“当参数按值传递时,const是毫无意义的,因为你不会修改调用者的对象。”

错误。

这是关于自我记录你的代码和你的假设。

如果你的代码有很多人在使用它,而你的函数并不重要,那么你应该标记“const”。 在编写行业代码时,你应该始终假定你的同事是精神病患者,试图尽可能地让你得到你(特别是因为它往往是你自己的未来)。

此外,正如前面提到的那样,它可能会帮助编译器优化一些东西(尽管这是一个很长的过程)。

Question

你用const去多远? 你是否只是在必要时使函数成为const ,或者你是否全力以赴地使用它? 例如,设想一个简单的带有单个布尔参数的增变器:

void SetValue(const bool b) { my_val_ = b; }

那个const实际上有用吗? 我个人选择广泛使用它,包括参数,但在这种情况下,我想知道它是否值得?

我也惊讶地发现,你可以在函数声明中忽略const的参数,但可以将它包含在函数定义中,例如:

.h文件

void func(int n, long l);

.cpp文件

void func(const int n, const long l)

是否有一个原因? 这对我来说似乎有点不寻常。




啊,一个艰难的。 一方面,声明是一个契约,它根据值传递一个const参数是没有意义的。 另一方面,如果你看看函数的实现,如果你声明了一个参数常量,那么你给编译器更多的机会来优化。




All the consts in your examples have no purpose. C++ is pass-by-value by default, so the function gets copies of those ints and booleans. Even if the function does modify them, the caller's copy is not affected.

So I'd avoid extra consts because

  • They're redudant
  • They clutter up the text
  • They prevent me from changing the passed in value in cases where it might be useful or efficient.



以下两行在功能上是等同的:

int foo (int a);
int foo (const int a);

显然,如果它是以第二种方式定义的,你将无法修改foo的主体,但与外部没有区别。

const真正派上用场的地方是使用引用或指针参数:

int foo (const BigStruct &a);
int foo (const BigStruct *a);

这说的是,foo可以接受一个大参数,也许是一个千兆字节大小的数据结构,而不需要复制它。 另外,它对调用者说,“Foo不会*改变该参数的内容。” 传递const引用也允许编译器做出某些性能决定。

*:除非它消除了常量,但这是另一篇文章。




Const参数只有在参数传递时才有用,例如引用或指针。 当编译器看到一个const参数时,它确保参数中使用的变量在函数体内不被修改。 为什么会有人想让按值参数保持不变? :-)




如果你使用->*.*运算符,这是必须的。

它阻止你写类似的东西

void foo(Bar *p) { if (++p->*member > 0) { ... } }

我现在差不多做了,而且这可能不符合你的意图。

我想说的是

void foo(Bar *p) { if (++(p->*member) > 0) { ... } }

如果我在Bar *p之间放置了一个const ,编译器会告诉我这一点。




Being a VB.NET programmer that needs to use a C++ program with 50+ exposed functions, and a .h file that sporadically uses the const qualifier, it is difficult to know when to access a variable using ByRef or ByVal.

Of course the program tells you by generating an exception error on the line where you made the mistake, but then you need to guess which of the 2-10 parameters is wrong.

So now I have the distasteful task of trying to convince a developer that they should really define their variables (in the .h file) in a manner that allows an automated method of creating all of the VB.NET function definitions easily. They will then smugly say, "read the ... documentation."

I have written an awk script that parses a .h file, and creates all of the Declare Function commands, but without an indicator as to which variables are R/O vs R/W, it only does half the job.

编辑:

At the encouragement of another user I am adding the following;

Here is an example of a (IMO) poorly formed .h entry;

typedef int (EE_STDCALL *Do_SomethingPtr)( int smfID, const char* cursor_name, const char* sql );

The resultant VB from my script;

    Declare Function Do_Something Lib "SomeOther.DLL" (ByRef smfID As Integer, ByVal cursor_name As String, ByVal sql As String) As Integer

Note the missing "const" on the first parameter. Without it, a program (or another developer) has no Idea the 1st parameter should be passed "ByVal." By adding the "const" it makes the .h file self documenting so that developers using other languages can easily write working code.




我不会把常量放在这样的参数上 - 每个人都已经知道一个布尔值(而不是布尔值)是常量,因此添加它会让人们想“等等,什么?” 甚至你通过引用传递参数。




在这篇关于comp.lang.c ++的旧文章“Guru of the Week”中有关于这个主题的很好的讨论。

相应的GOTW文章可在Herb Sutter的网站上here




我可以使用const。 参数Const表示它们不应该改变它们的值。 通过参考传递时这特别有价值。 const函数声明该函数不应该改变类成员。




我不使用const作为值传递参数。 调用者不关心你是否修改参数,它是一个实现细节。

真正重要的是,如果方法不修改它们的实例,则将方法标记为常量。 这样做,因为否则,你可能会得到很多const_cast <>或者你可能会发现标记一个方法const需要改变很多代码,因为它调用了其他应该标记为const的方法。

如果我不需要修改它们,我也倾向于标记局部变量const。 我相信通过使代码更易于识别“移动部分”,使代码更易于理解。




There's really no reason to make a value-parameter "const" as the function can only modify a copy of the variable anyway.

The reason to use "const" is if you're passing something bigger (eg a struct with lots of members) by reference, in which case it ensures that the function can't modify it; or rather, the compiler will complain if you try to modify it in the conventional way. It prevents it from being accidentally modified.







const应该是C ++中的默认值。 喜欢这个 :

int i = 5 ; // i is a constant

var int i = 5 ; // i is a real variable



标记值参数'const'绝对是一种主观的东西。

不过,我实际上更喜欢标记值参数const,就像在你的例子中一样。

void func(const int n, const long l) { /* ... */ }

我的价值在于清楚地表明函数永远不会改变函数参数值。 它们在开始和结束时会有相同的价值。 对我而言,这是保持一种非常实用的编程风格的一部分。

对于一个简短的函数来说,在'const'那里可以浪费时间/空间,因为通常很明显参数不会被函数修改。

然而对于一个更大的函数,它是一种实现文档的形式,并且由编译器执行。

我可以肯定,如果我用'n'和'l'做一些计算,我可以重构/移动这个计算,而不用担心会得到不同的结果,因为我错过了一个或两个变化的地方。

由于它是一个实现细节,因此不需要在头中声明值参数const,就像不需要声明与实现使用的名称相同的函数参数一样。