做一个基本的(非指针)参数const是有意义的吗? [英] Does it ever make sense to make a fundamental (non-pointer) parameter const?

查看:172
本文介绍了做一个基本的(非指针)参数const是有意义的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近与另一个C ++开发人员交流了以下使用 const

I recently had an exchange with another C++ developer about the following use of const:

void Foo(const int bar);

他觉得以这种方式使用 const 是好的做法。

He felt that using const in this way was good practice.

我认为它对函数的调用者没有任何作用(因为参数的副本将被传递,没有额外的保证关于重写的安全性)。此外,这样做可以防止 Foo 的实现者修改其参数的私有副本。

I argued that it does nothing for the caller of the function (since a copy of the argument was going to be passed, there is no additional guarantee of safety with regard to overwrite). In addition, doing this prevents the implementer of Foo from modifying their private copy of the argument. So, it both mandates and advertises an implementation detail.

不是世界的尽头,但肯定不是推荐的好习惯。

Not the end of the world, but certainly not something to be recommended as good practice.

我很好奇别人对这个问题的看法。

I'm curious as to what others think on this issue.

好的,我没有意识到参数的常数没有考虑到函数的签名。因此,可以在实现(.cpp)中将参数标记为 const ,而不是在头文件(.h)中 - 并且编译器很好。在这种情况下,我想政策应该是相同的,使局部变量const。

OK, I didn't realize that const-ness of the arguments didn't factor into the signature of the function. So, it is possible to mark the arguments as const in the implementation (.cpp), and not in the header (.h) - and the compiler is fine with that. That being the case, I guess the policy should be the same for making local variables const.

可以让标题和源文件中具有不同查看签名的参数使其他人感到困惑(因为它会让我困惑)。虽然我尝试按照我写的任何最低惊讶原则,我想开发人员认为这是合理的

One could make the argument that having different looking signatures in the header and source file would confuse others (as it would have confused me). While I try to follow the Principle of Least Astonishment with whatever I write, I guess it's reasonable to expect developers to recognize this as legal and useful.

推荐答案

记住 if(NULL == p) pattern?



有很多人会告诉你必须写这样的代码:

Remember the if(NULL == p) pattern ?

There are a lot of people who will tell a "you must write code like this":

if(NULL == myPointer) { /* etc. */ }

而不是

if(myPointer == NULL) { /* etc. */ }

原理是第一个版本将保护编码器免于代码打字错误,例如将==替换为=因为它禁止为一个常量赋值)。

The rationale is that the first version will protect the coder from code typos like replacing "==" with "=" (because it is forbidden to assign a value to a constant value).

下面的代码可以看作是这个受限的扩展 if(NULL = = p) pattern:

The following can then be considered an extension of this limited if(NULL == p) pattern:

无论类型如何,const是一个限定符,我添加到编译器说我不指望该值改变,所以发送给我一个编译器错误信息,我应该

No matter the type, "const" is a qualifier that I add to say to the compiler that "I don't expect the value to change, so send me a compiler error message should I lie".

例如,这种代码将显示编译器可以帮助我的情况:

For example, this kind of code will show when the compiler can help me:

void bar_const(const int & param) ;
void bar_non_const(int & param) ;

void foo(const int param)
{
   const int value = getValue() ;

   if(param == 25) { /* Etc. */ } // Ok
   if(value == 25) { /* Etc. */ } // Ok

   if(param = 25) { /* Etc. */ } // COMPILE ERROR
   if(value = 25) { /* Etc. */ } // COMPILE ERROR

   bar_const(param) ;  // Ok
   bar_const(value) ;  // Ok

   bar_non_const(param) ;  // COMPILE ERROR
   bar_non_const(value) ;  // COMPILE ERROR

   // Here, I expect to continue to use "param" and "value" with
   // their original values, so having some random code or error
   // change it would be a runtime error...
}

,这可以通过代码输入或在函数调用中的一些错误发生,将被编译器捕获,这是一件好事。

In those cases, which can happen either by code typo or some mistake in function call, will be caught by the compiler, which is a good thing.

会发生以下情况:

void foo(const int param) ;

和:

void foo(int param) ;

有相同的签名。

是一件好事,因为,如果函数实现者决定一个参数被认为是const里面的函数,用户不应该,不需要知道它。

This is a good thing, because, if the function implementer decides a parameter is considered const inside the function, the user should not, and does not need to know it.

解释为什么我的函数声明给用户省略了const:

This explains why my functions declarations to the users omit the const:

void bar(int param, const char * p) ;

尽可能保持声明清晰,而我的函数定义尽可能多地添加: / p>

to keep the declaration as clear as possible, while my function definition adds it as much as possible:

void bar(const int param, const char * const p)
{
   // etc.
}

以使我的代码尽可能稳健。

to make my code as robust as possible.

我被我的模式咬了。

对于一些将保持匿名的编译器(其名称以 Sol 开头并以 aris CC 结尾) ,上面的两个签名可以被认为是不同的(取决于上下文),因此,运行时链接将可能失败。

On some broken compiler that will remain anonymous (whose name starts with "Sol" and ends with "aris CC"), the two signatures above can be considered as different (depending on context), and thus, the runtime link will perhaps fail.

项目是在Unix平台上编译的(Linux和Solaris),在这些平台上,未定义的符号在执行时会被解析,这会在进程执行过程中引发运行时错误。

As the project was compiled on a Unix platforms too (Linux and Solaris), on those platforms, undefined symbols were left to be resolved at execution, which provoked a runtime error in the middle of the execution of the process.

所以,因为我不得不支持所说的编译器,我结束污染甚至我的头部与consted原型。

So, because I had to support the said compiler, I ended polluting even my headers with consted prototypes.

但我仍然认为这

注意:Sun Microsystems甚至有一个球来隐藏他们的破碎的mangling与一个这是邪恶的模式反正所以你不应该使用它声明。请参阅 http://docs.oracle.com/cd /E19059-01/stud.9/817-6698/Ch1.Intro.html#71468

Note: Sun Microsystems even had the balls to hide their broken mangling with an "it is evil pattern anyway so you should not use it" declaration. see http://docs.oracle.com/cd/E19059-01/stud.9/817-6698/Ch1.Intro.html#71468

必须注意的是,Bjarne Stroustrup似乎一直反对考虑 void foo(int) void foo(const int)

It must be noted that Bjarne Stroustrup seems to be have been opposed to considering void foo(int) the same prototype as void foo(const int):


例如,[...] void f(T)和void f(const T)表示相同的函数的规则(由于C兼容性原因由Tom
Plum提出)

Not every feature accepted is in my opinion an improvement, though. For example, [...] the rule that void f(T) and void f(const T) denote the same function (proposed by Tom Plum for C compatibility reasons) [have] the dubious distinction of having been voted into C++ "over my dead body".

资料来源:Bjarne Stroustrup

现实世界中的语言:C ++ 1991-2006 5。语言特点:1991-1998 ,p21。

http:// www .stroustrup.com / hopl-almost-final.pdf

Source: Bjarne Stroustrup
Evolving a language in and for the real world: C++ 1991-2006, 5. Language Features: 1991-1998, p21.
http://www.stroustrup.com/hopl-almost-final.pdf

这有趣的是,Herb Sutter提供了相反的观点:

This is amusing to consider Herb Sutter offers the opposite viewpoint:


指南:避免在函数声明中使用const传递值参数。

Guideline: Avoid const pass-by-value parameters in function declarations. Still make the parameter const in the same function's definition if it won't be modified.

资料来源:Herb Sutter

异常C ++ 项目43:Const-Correctness ,p177-178。

Source: Herb Sutter
Exceptional C++, Item 43: Const-Correctness, p177-178.

这篇关于做一个基本的(非指针)参数const是有意义的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆