还记得if(NULL == p)
图案吗?
有很多人会说“你必须编写这样的代码”:
if(NULL == myPointer) { /* etc. */ }
代替
if(myPointer == NULL) { /* etc. */ }
理由是第一个版本将保护编码人员免受代码拼写错误的影响,例如将“==”替换为“=”(因为禁止将值分配给常量值)。
然后可以将以下内容视为此有限if(NULL == p)
模式的扩展:
为什么 const-ing 参数对编码器有用
无论是哪种类型,“const”都是我添加的限定符,以对编译器说“我不希望值改变,所以如果我撒谎,请给我发送编译器错误消息”。
例如,这种代码将显示编译器何时可以帮助我:
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...
}
在这些情况下,无论是代码拼写错误还是函数调用中的一些错误,都会被编译器捕获,这是一件好事。
为什么它对用户不重要
发生这种情况:
void foo(const int param) ;
和:
void foo(int param) ;
有相同的签名。
这是一件好事,因为如果函数实现者决定一个参数在函数内部被认为是 const,那么用户不应该也不需要知道它。
这解释了为什么我对用户的函数声明省略了 const:
void bar(int param, const char * p) ;
为了使声明尽可能清晰,而我的函数定义尽可能地添加它:
void bar(const int param, const char * const p)
{
// etc.
}
使我的代码尽可能健壮。
为什么在现实世界中,它可能会破裂
不过,我被我的模式咬了。
在一些将保持匿名的损坏编译器(其名称以“ Sol ”开头并以“ aris CC ”结尾)上,上面的两个签名可以被认为是不同的(取决于上下文),因此,运行时链接可能会失败。
由于该项目也是在 Unix 平台(Linux 和 Solaris)上编译的,因此在这些平台上,未定义的符号在执行时需要解析,这会在进程执行过程中引发运行时错误。
所以,因为我必须支持上述编译器,所以我什至用 consted 原型结束了我的头文件。
但是我仍然认为这种在函数定义中添加 const 的模式是一种很好的模式。
注意:Sun Microsystems 甚至有能力用“无论如何都是邪恶的模式,所以你不应该使用它”声明来隐藏他们破碎的破坏。请参阅http://docs.oracle.com/cd/E19059-01/stud.9/817-6698/Ch1.Intro.html#71468
最后一点
必须指出的是,Bjarne Stroustrup 似乎一直反对考虑void foo(int)
与以下相同的原型void foo(const int)
:
不过,在我看来,并非所有接受的功能都是一种改进。例如,[...] void f(T) 和 void f(const T) 表示相同函数的规则(由 Tom Plum 出于 C 兼容性原因提出)[有] 被选入 C++ 的可疑区别“越过我的尸体”。
资料来源:Bjarne Stroustrup
在现实世界中发展一种语言:C++ 1991-2006,5 .语言特征:1991-1998,p21。
http://www.stroustrup.com/hopl-almost-final.pdf
考虑到 Herb Sutter 提出相反的观点,这很有趣:
指南:避免在函数声明中使用 const 值传递参数。如果不修改,仍将参数 const 放在同一函数的定义中。
资料来源:Herb Sutter
Exceptional C++,第 43 条:Const- Correctness,p177-178。